From 9ed24dd3b14c7d9c3f3b2c710c474423228efe9d Mon Sep 17 00:00:00 2001 From: hecomi Date: Thu, 5 Jan 2017 18:55:04 +0900 Subject: [PATCH] modify timing to fetch metadata and add it to frame data #10 --- .../Plugins/x86_64/uDesktopDuplication.dll | Bin 92672 -> 93184 bytes .../uDesktopDuplication/Common.h | 26 +++- .../uDesktopDuplication/Duplicator.cpp | 126 ++++++++++++++++-- .../uDesktopDuplication/Duplicator.h | 16 +++ .../uDesktopDuplication/Monitor.cpp | 114 ++-------------- .../uDesktopDuplication/Monitor.h | 7 - 6 files changed, 166 insertions(+), 123 deletions(-) diff --git a/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll b/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll index 4200a5715178ea7d054ecff05a2ae066b25b4f09..8f6aa9994ab209a79f02b223fa27e1ef4b92ec9b 100644 GIT binary patch delta 34770 zcmchAd0doL7yt7-FbK%72%~^3qoU%DqJ|3!iaID5DJr?*np!C;nC3DVYK|j?-V!S_ zdtECt6m!pTNpVTZtS~JxTOQJS(btUD`F+p5cVJL^fB*d6-}Cw0Ip^N{J?EaguW0Ti zLvFdD$V+X~a7KnAzbd7vxxVJBD4!$XRS|ggQ`TA?8(uU(RdU@GB_>5xf>lIqRFw*% zxvH{*ZBd`}c68E*tJk)?aI>4rVj7P~RQUPf{E^oUPSbvhOq# zyQl@KQ`z@`O)vI!^H3Xob5>FGzM+a@$v3XL1d?|my3((NwQ&z=v76%l)11ehbH-i! zP*KjEI|q0-m{M8xA)D^rQ#<)0+wR`l=hYV#JJg7N zfZ$5=hsB`=P1Dj2u!wq5+L`^uN%ewMZO=Y7((|g?l|ACMT1(o?&Un3~`R-+z-oI#9 z_7sn(e_7RTRkBXTMcP}(*)HQ~^%3Ul+gkNu-Fz3SPq4kdPiQ@ku}Hs@+Ve%lKlmM1 zwP`!qmVg0T(oXhsK&TeIlX*9ILi^)gHmAWk)9oFUy{RoNdEZr7Z2hWldg@>AVCjK# zv<`>a>A*hP%|px>G*A2C9rk=sD|I2;74%B0@82e&c@X*mLIbLA*0tz&buTHU_ zwAeqh*e~cm94ek;ic(FlyhZRVz`qB)Kc%t!Ew-a!4{g>#R@rcb*7mL9K87YK%{tQ{JeR-8F4Q;ROy;{5{bfTtCX2IdfTH|fS6T@Rv?eb;za>M{Ni+vRlqkULj z>=)^$X+Li$Ha9V<+O^k;{qS%jH?5P7RvFG%buND6gb<@rN)j}Ei2!*yS zWZy*3QJ-PMTP@SBf6TsW6|6qb?zLL1=CYjD7R_;veb~B#`aqr-4j z9mw1|j?^L<8`rU~_T?J3x#MHn^K00z9b2g5SVX6m+9PY&fKI*CLbkk9b9ENm(Wy`? zUXRLZT$~yEooZ@nR}{a!$8TyyD$J`QL-wp>BfDJGDs08=yXLD}<%jHpN7}24*sVuq zs>y70TnFu|BP>7exGP?)x)sAx;R;gsafmV6UaRTOeclv(e$mc838Ogp}eo$VH? zwOr1A=$5RuWgWYxtM%CO?yI!lmlg;0=&fo8^4PGR{k5Y9+3P*qtFNhkS zDvsLvxZ{>(_p+N>di*gvJca7ubNy?kD6u8?!&2<0VlV2MYoGuEn=D;={4uA}88hy?0E__CCnF;f&=hGd@gPv5hT` zkI)LXu?_L9+T}M#QN^C1QnZjnzG2WI$l6p(-ce77Y4A2hSyqzmX)kq{e%#9L#y3s= zduwgbLGZ{3gySssLH;K}Rf{bpDq%(6V25dkKzfmI0r&z7Wj_T8p^_cBY+SD}ZOK-) zs8?igInp^tM^JtMWuF8b!9R<&+zgKw5RA z`4<2hGm0{0v3nufZ`lc8kFyVwLsBm5-wLhv3c^FyLtn!+<=e?hhiUz0=*>GsmMhuy z9HuZ)h=Vc(c(O=#P;{(=UF|)F83zWigoKs>9~mk6GE4qofBk?DRIncxH)fNbYs_{g zc=~o7DPrx29azmyB($vOwH>3hPdU4jkRCCkiEI%4(AF>ai*=;f7U`D!VP(jGZex=Y zTWH7jvQ>#q126Nk$&rzR{Ppl^b~JH-^{MQ~mpBYcz1-}CC5{n9%}X5a%CjqSCYhDFRStik{$yfQATI;)sT3 zzoqw3VapuZ0jK)1+&&&{E>Qe02urdp@U+<7?E9CJSap5MyPMtOX-h3frpoo@K5SQ? zAgj_|Rr2Bk%#g@#VzC>l+MyICTHNy%cJxF9+Uk+z%*VuK)&#P|HLolvL+!wF>MgV9^8rM9ZW;WlqUY zElOl%?!W@~U0Y$bz!H?K{(-DSfoua5Mjv)Dx(r5_ke^EUi$;o) z=TLLJ06LDqn;r8U8uxufzGit2x18P-d4aqpw1Ka=sNvrrc@B4rU(!*`#%Rtcfp<`W zH-pezJVbLjj-t`$USdm)2=epK%Y`TQBA=i9TA`L5rs$+M_?TM%0QCZgX&8Vs zta7N0D-q)eE9=)iz1*_omOo|Z6lT7^9VmTU28O|`V6@vAVb0zQ`)*t8$z~dKmc9nP zmb}IOir>-#u>E51rPy+EF+`z-<)-BKD`R8($5=h6Fq1Dj95*qc8g&dl`X3lRPWAV! z2eWPlB5(ofL~lV5gZ?54EuoX6@^`W&-{4722dx$ZFwK1VoJ)$DYRT`1VU}96EvFQf zSU@?CahS??5x!q3%?MLzK(jW4L6-bBwJO{JfCSQ`j?lfdVj+#&4n zUsf{TlPu@}3#h#Mtw=$#h#$7XLc`k&cN`8(I%8H?mR-r=$a}~L>C2*Y%pBBBfZ{A+ zFeHl%sV@+G0Jqrd5j2Z!7|_H@@hCGprD6ZnQ816^{0I%!SmQZNeb?7cjV-}jx{Zy_ z4#R+hsl<_nacD56sIk#}^cM4jpMSqHzkvQRe*UQyegT6M;ID!|jjKx%>iGOwjs=_* zc{#85MxqJ(uvn7T`nXtIfQ)8)I}^n01JFE5j)P#dn3L?Or3lQyjPfkhVrp^?&JKc~ z*HdjRpyE*e-AR+TXgL9nA^r(|dr#feI+Y*}Ylw6D-W(Ke{`x3toXPf4(aH8XG0FBD ziDSo&VM~StF+*~z)FV65pb|WPz_5-cjg3J51sXn#T@kJ)dQ(BVA)Xo>k3WvMA&3*; zOahabSSB!gdZ-n(iQ>9#Pt367AExX$HhnME{(o!yeTbb?yF^QvgsR zeimCJ%8o&ANu3VT%?zd(zEL|Xu=&y1o;vDb5?rJ?B!il@oV znjIIfVhYM`9q&dYEWQO1U)Vik6Y})Rd32U0`fg8)3Io8pZiA3VCx;7p7C3q1yCRInA8&s{LnIR>i~3oQ@RP+BqL zY8O=&=oQOZEM#ds?D0wVELxh#MGG&HM)UY+2>ptEfG3uJ@%A!XUr*j|^_3VAEIrC= zN)uBTim$%K7AVT^$}{9g4;S8Z@Fv+G^|TN5M8N^5kF3JfGQi)~*WW%M$krFFjW4R4 zYvsIK(Mk3tROBi7w!37)YF-WYPiQntY*U7sNOgOzf+vf1YqcyZ@v~vUukh;dTlzg> zc#ZfiJxeUF6|<-ne-!zD{sjYRXRCe88&h;;2x=oQ{>z5cn^8VyOMdv?C{@g*o(VLKEdi$fD?IC9sGK(DWWGR|5N_Kwk*hjX8hs0QnE9Mw z_i~t4u0<0;{qe>VP98|aQEOm321bXi%AyP>MJ1raA@AsyK15JPN8V;t1LLOk2!bD_ z5!O_eMj)8FrD59!1affs3`(OjY_=OcASDaq1}!G}TE|%!;S&EA@OI;sKwcP!*{(E` z)feX3z(@uByyKyU|kPGTE zc^vQBWj>JjWNz64Kmi*K7$oH4nHm%=LmLM3T%6S-fE9g+x10{bxHi%_AE$9{4;a@` zCU*K1jEmyN-NO_njr%l$GUIBTQQ}_#-flb#D2&?y*n`G>9=uLudhj8(>UL{#zhwK&eKR37hg^5UHfHj-!0-NrlIh<%eFCrr*}c${SoXla{I3N za{DkjnhtZkYv;N5CgtaX{v7aj;~qc(dl@j~s7{Bl+CL@SDB$Y!i0SXqaOM2?cEOw% z|0ERAFq#5Q+|s^0W!Gw+#Zx}3dy%D+c2V+Og{9O%0&6U#R*&6fKU1m{xO{@J^@XXo z8b7R_U%)9J)zVHtU8?!Roow9ZP^(ecwjQF~HU_3{EqlqN9*4ZXr-;&94k=m76FJ_s zmS5i}(rd*{8wDt`(DR|D^(y2$-?RGP*ibvi{02Lz5S@kBSQ_|es5J0DVCov!L?(Cu zO7tLZ;P;rxq=Cmd-qparu-l>nu>l`vHy#2O7On>lBKHk1Ut`uJ>{wu33UB7S?7cTb ztu$X!#X4>4`+#k;WLjQi+axp(RBWwnfe+Z0D)E>3X1%^J?N-RcOq;S6J8NFCz`EG> z;SOH0^<~9ER#YsQy5;62(|R28`W}=zDi%`Cisg9Ma(f-yQcABCw`~-lRIz|PSZu@B zHWb*ukGfRs4u^w%y|r1Rp-)m|HCArf&2U7H&9J>xFPh7Ow{`R5$7DFN^u$V}^5^L+ zbI1lwo3du;Biid;tlQ8wUZpo^A!KOv277vFgn9h8@X_AO(~j!~WLe3pcK7R73X?n> zrs9?CouN&vB`a(9WlO>5E{sZ0vcIBbs)d%R^?7RgNXgg;#qdYes~Aek#jN@7jCq zRFUxauT#RwC z(voc4b;xiW1KQp4=CSL;g8WB3!BwQ7*iaIeCoseCmez6)95&g1OSYHOfdp15I9W2i zgQX%J7sOcdySxEDx#nCf*xmqJB8O=_%&{9^gD~I=#maJu3k>^k+B)_5fLd?1fDIF{ z-Yzh^sS#Hf$kn9^T>BtaGCZ{Fox{|GV1yXT#YUv^&#kUQIX_(Ah0QWf#+P37Th@L8 z^B>WyWh?Z7n#~oRm{-=jRU>9ub}_pFTI%7~*vJt*aFw!l#G|;N`hLW?;1}JIZ#s4F zSCx`K%RkvZ+%wtktCz4b8NtE7Vjb)-y#hSs^IV4;42S8=VtCrK>6tHke!PYP9E;eY@$FdW@!iy!Y{vM0o*_JV5CxA? zPqIc6I;fws0TX(SdSVd{9tP&SFGE96Eb(+TIlJe*W07>sJ&58g_CD2?9>-?G--G+x zlv(nA_nZTN8}85hz2#hZA_Tb1Vn4(8Nn?kziV1Prp9@&%#K>+}7I0Oi`jKHsCO-rB zZZ|3{w!U=l_6`Nv%Pn>^jk77(>87+fX0bgLmF6&gyMWD}I5DHqLP#ect#D6XQeDTw zzlGWw3xDSRS_{ACere$+0$gKZz%bTsQd{lNvuxC)h(WJCD=l1{{(yx~Qjoozng?!< z&_bxMWa?%Eov-*(u*H7I(&jdeVZr+2?8KzmVP}Ry27_1J1Dm?eFR&q#;McB&RNs&`Xx7KwXVTU{!_!Jay11ItXT^C`i(dEd%R%GDPb(HGx zS_5MrF!1RWN+K8d?H$6l5f=K?wNM(kb&1e@9#B3_iT&-hms#Z0wXxfx& zvlC~u!8N-4F}D0kix!c}%APa_+{NjV7=5du`+JAN)Te?%FOcn!#;*OWKJuo+kv}4V z*ba}e4o`(?AEmI=rO!+?}O58xlCE1T6mka(<*i$ot z8%F;`4UF!4v1E9;1nUhCJ-aE3m}Akr2eNNxbZK#xY(IZ%$>{(r{r0nAk0S93* zXdH?@?j_cHW@uZxgtp3E&{N57rq7WAhxGdeLSACaW;P8;g~_QXJkPvRI%u=tBpO!+ z`i3x8GP9?(`gfEzj*|^Hz|bck4#OAlbN<{poAJ&qT=qJ*gE+=AF8R$R0RCxp{C2}? zDkmhW;!M;MY-wZhw;cV=-7@hgX+hD<;_;_*tZto3j#utLW^1%_fZ;Kzz#Uc}w%@yK?wSv-&9PChv3CPM1e-=W_X z)^=8~`&6tFnR!lsZR`M6FsrR8`T=A^AU~O9Ru8c|v$kl%`m^!N8nL3;jXH<_SgSO7 zBD(39qG=dVUexDu=(>ki==j0nF+D0;-_8D*-9+2}G;bfv`?0BWItN)QYt;w^U8`9U z4koU#^K-Up^OBHYC@aVg3yRb4N4EHtm1H+j&$4f_H>gjsqw{+NMgMR=sNp?UmeYjn z&sndIWuH77$$Sm&NHmhYH#a=U^Sk?T_x{5w<~C&w=B-zI zvD*tH+0MBULDe_zhkbvC+h%7?=WoDs7Ikr_@C?2-Ku6cVxgY)c?KSh8vQE!#(878l z?Fi<-C_M1`{iu^w%)Fq9`XuYK;0>*QJb>XWcTQMPX~q4>z5nK^k77d>ZqWYh!BuX| z2@BeP?SACepIOYprfkBZ4ce{l9A{n}7PS2*;Bf!s-l^nfvZ%a|S=!=-reGOiK;ykR zK*aQ9*B37^tw2X25!aXKgN?(6)-LMoc-iuKQ&EWKEVV zFj*cF^Ay{)WPap9YD#E%gM^|RmubAg-osO$*Ad$t`NX1cqxdg@lii`F*+y5gBhQ7X zpRw}i#(M4T0tDu&3^sF4yYzXNYw@CqPNAj<>uBJqd>cc{gKfQjIi>D8G7ix91z@LC zWwB%IW9?Q1vwaI9nfKB`+S{E`@L{ORaBKPfNexGXhIZPKp(*ka+OOeSkG$IRN#4rAS( zPtnH5!n{CM@=Un(i~G%MNd3rJ5-632l*A!=eNflLB@Z!iQbw(b7VxzuzFHGwbeP&x zl>M3Pqd&V#BO_VcD=F@)ROlb-{6&Vf8K9=gLhVdOZ5ir*m`?QqwQ-XYU|^Vp>E38tjs=G8`74USEZW# z&?yQ|4T!^w2uH$-nLX)*wmy4q)fk^@Dsc2&5B<{)?5|au*oORtRzKTo6r3NPe3h>M zMxKX{Zw$J@Uw7y7#CU{Yap72sjlsxSwAgP8I5g7ftQW_-?p*px`~~3cMio%NzPZ9B zoI97na$|6Aq|m(?SiUjP56-~rCt@x6h19`LX%;fn{^AM{hw0{{)KYTjV4xJT`k_3) zSF#~53~1XQt6(g#>0)^kMU6!iU#^pU{!3B0oZ?(Y-)v+by|BC96O^kzcCy7UHnz6M zVzGcf8^fuXo+*5*qR0X&J8>eX&ufdqs(q0b0AtSi`Q!1RUqBvLpLZgYS`sZAEcO$_ zM!KgrbRm=y=rBT)*!q|Va*mso^m;ZtoT%uDcPvQ#G2RwSN zj2Y_^b0>vj?08#&t3sUVxx9k#EP&T<>GQN{&HIqLD7H0S`4-lV#_}|j0WS2dC}7@y z>G6XoDumjXM&&}FTT)b--?CT0Az-NpNcUSt6%zXsof#yE%kh+%D8m$c42{hRRBE^v zr%3+5BH8Xi=_MrNT&o}f^$UaLJvm_3r|77W9%2Y#dT4+}U?JHgUYc+?Y4uw=pIS$) z=E`ZjwHRAq_|o6XMWyG*&qgWc#pj)YIB(Sx;1{jhd9_$D1|jGp(M!;(^Q=!(TO9_x zY}TE)05xmp-QrVHpc*OIjjaJiv#t*qBxJKDDBa3^hCz#Tf6R?B{GJ9cE&o%nA4tdR zFfX)JUif+&f3oxHX{*!FLo^N4xdW{nEtD;RGX3gPl=#lmHFnxL-qp^JB>pjOXC9!i za}r<=+SyCm*&^3UrDm|#8oG*CG;Dp5!eo=s7yIGmM&CRf)?^!TsERgx7m96`IB-9L zvs>bNJnET)E;t<3c|jkHY~@l%5;mnk`KGb=ORZ&I2((dXV zoCeT4niBZMJDMluJDRb_*~fV6|8yylT!m?0e_H*Up*| z$+a=NDaQV2mSz7tZ;Q|J>vhY~AKmT8D9r?@#}gD*u(pkM`6T;b?IP{ibk?&lIcNYD z1eF$)M~dy~FRZ+KfHi7UDvc8O&mH~zy_^r;vRDl zyNj%Kjk+ysPMJ&HNBzy9KLcM9700j(c;%xfb>flNc-Nv=J4UEHPHG|+u#$C=s+m=+ z>#1dWu!vVev|l`myS?(NrX4V_&t8kwmKvD%`WS79f%OD28`zBX&rhSLOL_67R5_SD z-ooI{``1PqOYsJ%RPd=dI5v0rG!_j!6hhs?lWqNyp z{3!?MHHrRMW5{FeLDt-V7HLSs631f0G08JH;lY_Ey?FOYw&Mlhd42P%G!fCeU0bYt z95j{MkQEQf#@6npYp)1z9zmk0i*x5>;T{K5w=Qnec!RpI<)ALU9Zy5ZUP#HIj&Z!} z4F0jiKMuUzXb03{*Gx~b)muyCA2MsI}z=O^J2RLBl2fE#UEF<^xLIbQrMO;f$_@Y1rMH(n#307+4qEUL4D>^zD$P zf_e(VycJI5iPbp+rN)KKwIbt|W>Sj7Atehc_5tIbmiXW15VVaj&gY@Vtqqn1cOF<5 zry1XHI+U8gn+zixLU%-6<2sCCA8u)CZ7PiG;s#+{Vd3!{H}NjbE!;%sGx4T8$@BWb*)Y+> zP5j{yCFr;GRmvZpigOuiY|cm5zYnH}^ZIhg;Hfy^fV~13%$&+|WUj$37$UHvI5uBk zXPjoaTZ3D5j;Fh_DI#oukeAOEC@KCR30G>ycy@GaqiI2-#o-RFt^6yu71o^e$R~nJ zZso#WyU_r3&U?G;3|zupErkWPJz`;)-{oU?YcJYxGJ9Tsm9LP`9pqPh@0PM%+k&+@ zv)I{f=Nld8#Z!A=%|{B~P*$`(%)0$RZAvvagbPklYT|})CivQ{$FB%Qv&F0?ZwXI7 zUQ=%3nHqmwnQ1qc?x)P)FNUgN&O%uB#z~P8jNn}u_y;pGjHmn}1Od+i1d{O_#(sOt z=-U-G*o{*~bTUhPCq%2)oppHo-QMf=xui88!ZSY-X<&bISq92@;kZr^o#DMjaH?!VAbpy|mIB2~;TUB-d0 zmFB6osRJp~8Mdgatzesk&AQU&ox+zvgQ`e*wFFoa!W~UM4lQ z_n%_69eu6a-*>fVi?CT7G|Ge8x3*N)p?~KvDKgKe5#%u3w zXK(BbY33e;969$42K|>nc)PX9UPvoxtTxZ9ZE*jcm@3#0r% z*73b4^;b6hy;SYZ-E7Ny=6cuq0C;RFJNMok&A5#v7KQtdZ9r-82jW;wr8Ov?QS_Rs zZAxeLcc+DV>(@N7W*cMx=2Sm_lryH2)Lgw=I$OAVYs1I;yR6$%5}gG<9z}$|MByW-`~I3ch4178(PI~z8|ACsbb-KH#cjH zAx%GtIWqQ2CFT}bhKB~ODW7>1DfeY9_l;?|q9?F!z+$5$?Dx>4>a$n(b+`IsjL?fQ zn_==>h#r&|pZ_+r@iF`<`0GwHuOd;JW;#Kao}Wq!x3M+wcn)`6xIH7`lr+{&N@qyp z9xa#5&F_cxP10EUn*>8JkKk*#enqq_qQzTZ8HlcGcnt#pUoJsx9Wk_cdsPBx@%9o0 zqI((UOC&AcLb|YB`vco8>>`A*#Y$a;UCSl%=bMs&)EE9tO(CCKg#E=B1G~L{ux5CR zB_0R~^w#N5LMq>*E#xvsj?jb$GgsQr?{N)GI__Je|hxOamxaTuV-{)d<2RkZWG z_@A~Ro4g#)!C$u=eKcVt-`H zd7o7s47YYgARm486bt1B#*k6SPFptuu8%4s|B@3MLB@?8Q@c>CxuPah(ExmqFt^z4 z0gF3I3r>%L#Zlbidt151Bk82)(>+j7XKiMb0(XpVH=!VejLS}@1p5o)$hKw=*fvJuD>2dIDX6gR z&*F#Kc0O1dcLZ1$<1X|UPeEx!g>gF|%#GUwrfyw-5+{tC1_k;F)DWJ6LJGw|#?9e) z*SdaJ;=6I>a4Ep|@pV-(c`1AK%tG znh$J_QK@+f{~gSK)A;WY{+rH!hx6YI{yP%C&Ref3Q~V;ABJqTI=8U^#l! zf6A{%9gaIW+MVN;qo@5VTY9n&KbWN@y5mi}S825k_y z?DQeDPQ@?j_zFYgw;22I@m2-f0inOx#73JgM4rX|^d$=0#l!qwD!GYMI@6LjnW>~x z`!0w{vGuEf)A6@LM62%j1sK~Q{0{zz2!A|eXvO&eW5?|*r=)d*pJE)2ocWfC26IR1 zx2CUR*shY7gW6N~;w2>dM{fMkZEWPxHtqd3BEo*ze#R1Ox`{@UcfGgeQ@pMD9b*Hv z-)25I0r8{LjC?eBR(!N$tbDVOZ+Ih$%hvqeaWFEgdsFE-PZ`ct-u#2+J=W;hTGNp& zh|2apP>*0+@q5a!eG5BwtXt=9%^;I+Yz?A+3I#auY^BFQ5|_YcWWr0tUu=r_cM*Te z&|?eha6DD(yoD`3-l>-Y&9PUOl~~s{BA(}IF zs|TV7A^}@??q>G$@sZlp&1~R_@3hHHSjUeRKhnjFMp5%NBlfhzbfqz63(o>Og`s_! zE^%+^K`(cugqN$u(Y&-V`~IV5)}d%O`rEt|kT6!RD||)BpZJ!IC^3vDN6LjWMttiwBy3MrnD?L2+B8_BH5de>B42Yx2cu! zcaedLqYu*_muXX{!L`71Spz z_xl&_(M}nDTF2fmjnM{dVLz1i4qUblm6VuQ>fXGnx5F>VX82_@>vlTMdIRJ-1g zy?Z8DyU>uGI@4SGxgqmBJ4Bn%kc~bY*|6C9?wV9^h}?_FtJ(!{X-Uu^B! zE4hCjL22yX8eY_avj!_HeKEJ#Z%9f>a&e157~_)AR8<6O6ZVI+_J zjK%V68QR<6ms#4mpfMfL4wM``pnV2X`>Da9N#k$xQH>wG36G=s6hvUhlW%+%{z_^v zsGMEkahiB5S|3n>u_n*cUH=}JF<>;Oyy2Hk?C3d@*O6qB=&~=FT|3v;>p9_Dkj&bA z{D}1+GT~@`nExK(za{+lOa6P6|DNQ(^v^9gn!n9|Z}H!I{8#6{p^YdujQ>XPUo-!0 z%73HyZwvk#&3{|--?sHQIUiW8f9#=Z5hhl3KCag!Tq{}fS4JbFl^HI4iVL40_yocP z2|kW^&p0;aLNnv>-cVudM@zwXlGxe{v3+j@QS){_emu$_KVINrwRdA5a)0gJ*n8YB z@5cTW#C*zn`nvb2HLg024KHiis!#kS2%<$_LYw#NK}XqFJo z5TXs7q6s8=w~N>bISpKjwGF>N%3o;_`03bc@T7S8e@i=?{FS_HtHC=bYnWyw06)yNIi;`=fYzvO5x+41i5T8Q|EA}SBo392B}uMm_e!U!_3GKh5N zuZ+Q;=%Ti3JWA!CooldM1RygBd@IA@&n5pQ_=N)WC1E(n-6B4JWdUIl$dvq*^N8Op z@GFR4C-^MlS49esnLN3IPaytVC?X43?!_>zU>@6WG1MBgT!cX>&qb8L^I{Elk@XRL z8tF-x$Bm#;uDlytBhO{Ng&(?jT)E&;B1+{siIas!Er!DVD(}9?1$g56i>&{rEwqwn z*o;q`TYsaMU%b_#$_UJ>^!OTt*7&0<=isCqN};cS(mC;5jXhjtkgy?v;yhjK`LmP2 zx!A*PjuPsi&$^NeT>=owIbSMxGbuYPc%DcR_=I8f@55N^KOUsxENnhA^lq*h$RMF- zrnmrcJCR|@JBDkY)J)yj!*v&Yl0awNmzke#v9>-r5;apD{=Yx1RuRI|lcp2>P$ku+=HoQN*8grWZ zqdv3J;aHi<&%?%4wr1BpiwJN4kz((cWgj+`=kN{Y`+3OYUDjdknr~I}>neQfFKpO{>{fz?yf$WEgNc!wzyt50}VlM+lx7>4fEXSts@ z3R#5NUoQ~QS>R>tNgiu`ofO3!AVs)x)jbYjmlDtoKR)=uT4)i)S7EZki@vA9(?=RA zZ($sFHWZ@HMNRl9N&|Oz_^a}>`uDiJKbSx=_OsM(M^*0m5xR)OKGc%O`hVeP{Q;$` zH~fyLcLh9-WpXMgk>kql@u(1dCnfctApGqm?IY=MNoPyCT+)q_?v?bMq~A-bO;j;7 z;j54d+?ABV=sP)7B0(J&NxIG|neCDuleA3I24h45%VkwqB=wN= z*bou_tfajp4U_cu$3%REq(>xuR+g-Fk4%VXA3qxsB z>2s3KlXQZloh2P8snl;(hKv&m`ba7xl;5S_KU2heNa~DlA>*$~g(szdx}?Dp-&)cn zNvBBq9H(f18)U#&pfA0PM2qhPP^Mt1eU$F^SmxucIQx&rmrj1E- zLp7J8)61ClRWB|3bJpjp79hpbzk0#Vl$4Y8)U=7?vuDok-rdPhW^Y_?!XmEE{)gBL z*CUf@R(0a*$VRs^$M-V#8<#wIcw$O&QsR&S?a7!{|Ac23ergoi)?8QHu&hbrvnQv{ zoI82QfbFbn$TNw)7Bv>Nu;H(_k`H!WDb8|}C+ zlBM4W2KV%hN3i*3TW_>sUV0i_I9vREL)Q7*r7TUK#8UJyR&gVQ{igRdwKDfYT`G!s zv6(7NG2>HM#~(~=aAhhR`a^S;TiKZ1_`wwPFeF=8`2_n^H?f!>ql#};KBYCibe8|? zmWt9*(1iAaR><)0&$4H4&9IhA?|Dgcy9-#1q)s(u-9-485?8B6;^PE0KO*QYiMu0d zwWO4_6>zd}eIM*U*l4{QIBAyjXG$6)X_};FnLx>8A-7S|f+u7G?E24uO2cE438w`ggQie7)*LRm+HF1FKrJj*hK6 z7B)4o5IRP>)QLt!@zEHmcVbPeTBzIEtUHZNSuT+To(F$4YhKk%%|LuhHHQCs;x~|u zz7wSCZ2W%$O@z$qSgY0@{#LYE(Q?@9^$ynleF7&44#Rfk#}9XD0O ze?N}Gm%8BSgmoiR@3zz|9a!tTEj0fQY~Y<1Y889zZlDQgpUR~6wOTzny4Bs5Y~$TD zjp9?f*2Ysla^b%}RYKg4%OD*4__ru_8!3@wdY4*FRIo)X@t23kOhrsH1LegG z=|(K!uD@E%t^-YBFLkcfL-{MBm=Ma#RaB|-!+t^W2Qr5J^lMbBhtxHx>e;(ifK1Bh z&ECG(0%^_qvzdVc_7mqtTvjjA)$VSjfzmW{1aYP8lY7m0SQfaJYBcwg@+x-p*OqDt z|1IFZnfy0~|0?)>ji(XA0;)x7I(zK5mg+|Sn?b)U?YCRJ9J1JL#KhoNluI>R{kz~w zzy-!ri*oN%n;9yNX!!51DZ<4i*5bV2&tyyf2&8{gQ7KBOjUi-70=1dPsu664mp%ee zgQVyv7dRLUJ0@XH_~ z&MuMbf}4Tz3?qBwXkd2IYnuoJ$YVs)YCIaH0vux zF@rk8qGDo{0t!QW5@GX{qHp)j^;Ta{t#M5dI1fvn@o1j?RfYCL!XGt{lsW&o==PHZ zhW^=Tcfw2~e-xfUVuZopZ<75oESAD72+Ke%%COE9MmqyK1C(K15mcDxqjphu6dv$V z=d`|h6|Dtl9Rm@8-MWK}Cc0kI?UL^Ks&Keb9jRqrE!=HX`-GBQ9ORyZU4$I70G zKfkXF@A;`strSP!PoPLr`302fSN)no6(t;$noEecrg(SqNTW1L>ZwXdeK)0kpL%H? zF-X%H*3?sJ+Sy+Tm~E`8U*T0!FUup7;?@CA_7*`G(ZisW7QVtlf7R$+1`zcUWN4?q z+Egq3y6~dEI(SH_G~zR9#2x8(HHMUj{6oT7GGXPKNZ99E;S2t1L)Y}y1R%ZOYlV9Q z)PdGu;OJ`(N}28>{jTYe&JZIS&IFP13NKaJh=nO-EFjEX3F};6@g3rwMH%0ZI0{db zdKQCH#tWoBv$c@h0gA5>|7=yq&`h)d8jC_gJ(T)G>QxxB+%w(Mv>4R#nFeZT18N}! zQ2ZP)qo$h#Mkh%@u_!O=^4IC{1dp zm9nz}ad?`e1a&ql9&5BLGPN87fU|SNKqq}YD>zXy5kXlyL;!p@L8;tSJV2!I5I;@v z7^20HT}9B7CBt6 z+zRUYl}N?6WI|P-B=4Rgk$x=Jd9 z;&YOgOPV!UB=im_eFs6wr0=D_Azmp`iS+`d@5*B`gHdjZm)c&@FfLG9B}i)m1j*>C z3heOBNSQpt$O3$mq(7vim(pxfv=Z65rP4rcs_=%NCX}p$5=|;mu5&TP2NXd{u%uBk zoTwN}1dWm5Bvp@}Fo2;szo$!tH^t(kso8>XAJBA3X>g*CsGp?d&l)N+LNDd%OHUUD zjR&QY$p)nf^d(R-=oL^8GzaBVFqBXwC?!-4Y6NXMO!zl}`oe!e`cHro{!36Yyb_cY zIzY*whQm?sps}D-vH@7&g-r5ByYQ-MPgy8IinC@SSH$pKjS#$h2Bh%?fU2M^K?$RJ zyDQ$E>(RKM)x@AFhR*Iv1>(j&j(TmODoucO^@rToh%HEzKJ!SSFC-ZG50)*~bGAEg z>1Kd(CEyq+eZM&cT>5#nHx?A5grcUP^d(5Y>v&uST$&6I2*ji{#Dk9$+Yyd`%gW)% zLJ8zbz*?zD_482tCe>H`I(sXAL+WR_4lub8ESX&RY>4bV8Sp!M&qnB~DNPuZHbwZ0 zLFo&8LinRWsVt^QzbL8N>WP6)`buQ{O;GxxrwVy7c-FV_fsDG9Cj@!`kR}1VdM0@& zY142i4Yv_ns3sKe;t%2N!mG|WQ-FUJjlPZ3MM4)r>8tmoOgP3{X*#K)64BYDG`Lu} zAyoC|L&#LfIcJNa>q6!*C}}GNr4Dcjlm^2J>34RdG^u+7D1GNaNzUUbAvY3~ zJ6|FFn?TW_8Y|^sD1jTGB&a=&AAAj;E*#ic)=~lt?1M0>ohleW-=Cm__xy%?l{Cmv zyiLl#4@&WOK}r83GlX9(Me%|Ge!>U1G|OP5QzpaRW^%n&r3IM#fmK*DB*^d~0;tTD z{*aa)=obN~8Gps|qC1}-OM#yNeWb@M4Q?xGu9Vv=^&AH!!{=s^0T^Rm07HTgQ@l|s zCTN+&dCVdo+AAn2Iw}2MgOVOhq;;CjJm{dWWR8emn9aS)zd#*E2sFJL5P$k$Xq1M6T%}v=@a8t&3wj3hiJ%DNSwoo3-?gMCwVEsm@m=0IZgpCZGq62 z4NBj3=~sh13-J##hFJX{uJrhAm&lA$WN%*Y~%~qO=qB1G?$V#DT4k#&lM*54T z|6vA2yXdKqxB+&dCl3@00Egpw8E~8jJiMH-1gmLLRT4L1l~BY$$)G~%|4jNHW>9%R ztsW&Ga!B9t1Q_}@Q2@Se(*K?GKTJ`Piz5FQgxs^B^zD`YgVKLb`X8ppy23?~`9-1V zc~JU}OaCe9Hx!8YhbhW*(Gw$a{BO~r=Tqtb0+c?}YM}=soE3ekKE_h-nmtJz6eUQ& zd{Fv!)(Sj;_XoaA#(S?3_}-vYl41z0t6%q575X1@DE`$ov;f6-;lBu!K%h#-w`KxA z4)mWASOF4wOFkHw8W*0B0MXyG1FIAsGOZB3fn>Es_SLNr9wILO~HI z#oquWL+Qyr`Dp_lnI54u?i{Z8s=*51fM<#gcnoy!29|J6{UzUEEFlHwkPzjhTqX#X ze=(bdz%o$!-jM!%pd=T%MaVS=b%Xy=>0bm&@dLI=!}z+vr)ITNAr~Kx$6-ws5_MXY zD+Nx0()S%GDQdD^VD4YVdLmc!(cc%4j*md;ySBYhi^ka~waxuV>^X!{ymCWOA5fAE zmi{Qvn(r-vc@LDntJ1H%Eo6K^sjyiFrz09(@By%=KPoLf>?zc^v= zQ@nS}6NX8?O6ETNmsM~(xK6Y&*8m}4RJ_+X1$>l({fe>+?y5ARj-MOhsT3Sgl=tC^ zItfGT_??CxgrRUXhLYdF0}B7uT5Z~b+Cv%I%mkDM74b$CW!WLYZ#c{gNjY-3@W<9_ zYuS1*KxXB>fej?(p9NHGtATXyyUx{w>DG4}^{vKSTh&^Pp5! zY6w)#eurPKd}Ux22#Ek0rY)bB9!+(DwMx|LMYz`S`YCTrQiIKh#w5%`6lc!?J_EJof>M5qq9*U_`K!sDj@h9k5pWsnM0=F7_P<{~PiGv^<2z9ETCP?V?e zMIEivXzfJ{LRwSN%9B=;w5p&504nbK2bTs%Yc+q;kqf#6i6Nfm?32jA z1-Q#_x8T%)s$znRhU+;H&nr{GWWY^?%Yn;-v%@jC*Wot7y#sd$?i}1@xa)8?;r@oJ zH%L_i;lkjW!F7U5fJ=tUfSU>TEZj=Cb#VWJdl&8?+^Iofs&Wa;HMpPPs^L6SR3#Ly zNy@$rG3qy(b^oK(uEn?eFspsxDe<3<{~T(y{Et>Y%Rhp2+MK_ z+k>!Zgq6Ca@h?1^%S9S#0*Bhir)R=405j8S6Y(66|6}(*Xe=&atr1p$uxOXCfe5RB z!UUIuvk+DdT!IU34TS+mm#fY%cw*t=&KM5kLul4`OTVI~%hd=d2CH(K- z`ifG2=u=;61po85zVfB*!=C!`M)<#e>-%4x`if5QKYr``U!MBnppL%(?OWgf^3>Og z?oZ$U^sO)S|I<_7A^-2+`tJKCPMy(UZ;D!8-)c@)l(TRaTw&qmp3-DG0z|%eK_`$$; z00uN@2qxG}c<37R1GsYVC7=mI;V3cCNpNHk-7wA`j)o9}F&gw99EB?*a5s^GX}%-y zpmYaEi&odWIJ%?z18xVxiP9Zh33&5JwC-$p%HW}UH=j|Mf5Fq;T7Nh*R>*XJHXqIc zp03J%hRXzB1^U8hVMGDw_%XPhAwxkE#|l0T^fnwfbey8R2}gVp=wq4St?*=mQOAo2 zf6%>fq^JaR`~(r61?oFdVnBCEz65mqB#8m_oh&h+&%&*Mp?E*3cuv8~6Y&0^gW+iD zPxo`yB~K{IVR-PUQaJ=i*3rdV>{JwWEI^=rr=dEC2X)@35e=M5WK z_T?g69C*56`F%c~kAPR6#mE51m4YTN5Io(kd<0iOcu=}LA&l!K3SF+`z+D1{=t?*p zJW&Q$4W3!Std|jZxvHFnBSmGPe@LDdfzBHi*P9f&Q7M9p!Q}|iZ{U)^6a5`79XzdI zofjrVSLI^Sjc}ry;H<0QDFfrP1crd86=b^P>GmW5tI5p>r&Z?@aAX{r*04c zy|@yM3p}mAzp+CIJS~myu0j_DPit&`i&zJOr!_eJTT`XrX)WFv%V+-{ zsAAA#a2eof-Tv4b7|{c>3oYQU!|g`|E$nA8)Dw6*#r1j#2K7V&psV35;AsQU|VTkoL1?2}LKo_lt zb>M07zXS{Tb>L|sPyZ881@WMB-w;DJ9i)xlhykiM@SsU=BKP3aK-+Fcy8ur|PK&ld ze*!R|-L^v~_yo{Na8#AnEHE!f4;}p|Zy_;&h(7%eiY^hk0d=0b5FPU#iWlKTHy2@! z08b|h)J9u1A zO6UZo*#WczgcDr__a|XMohK(m(+l#z)_BiKp#6J_)Jjstl;UaARn#@ z_ySP;{Q}4PpF{P*MdQygI)i4xk)C;=)?N6ad3_J4E_tGVNnZIFf^dW(8ZY?-&^O`s zK4V4!m*!4}jp>_QUwU9!v=wSw!@v^nPIq91jPj6My3Aq?JxtiKkOmI)Npg=o^y9LDf`#*pz~zrb8z>P$Cdf zIxZrf=v#1Az!ZTt_)g^54BAKXX`nAjek15bII5aUpbinfZ^=M)n7Vh88t2|_|E7{n zrJKq&m2axpq;IO)RJ}>r?77*0bMR*K=IG5ao8vYoY_@Dp+nljEbMw@~N2jWd!pb(6 zZ?4#^Z?4*0vZZuO*_QGx6gJC|e7cPgPrl7j50YwPb7Q*0QbTTPwEeTdTHK WZ?$Yo+m^8{bKBH?SEj1X)&B#`hm=DA delta 33994 zcmeIaXINBM)HZz1fq?-W8G2E0Kvb|Gc2H4N&_O}5cf}He9Tki%85B$$M+~}+*kXvW zU^EGev87>&B^pJO7>t^bm@))oFvXZU@4fcf0|WZJ@1O7A_nhn6bMJDmwb!m^mjgK! znw(EHC2n$<$GkC;cxt3@gNM>sl0HSmHZ^k2HP%|56e10fr5tBT${8d}fijYcWT}!c zN0u_#9(lI={7(?l!+pwvmC(jH3*oJS%Yv(5{gqa73Y(_{H_n89lH%MEY%>z3v-j~k zgMF{GV&5s=teMmA0ShlmlC@v3BpLH{|6Bv)o{g+}eE0zOnk@sc4m9JCrGFlmPzpFHwlO9!Tt@B=IBYYMq zADmzpeflcPPcWVD66Klw>;>N_`8GS`yESTYF$pb!&<_wA@Tl6uXt`odr&!CQ6w5iI z~Nbod8{*VQRBrB%frPD%UWF_tk_EP8oxt!ezjZvE2EcI;W zsVL9wC^dxXWM%&L()QuSioV5GNwSNM75K?^-ChQ8^yl6iG35f zNdBCSidwDoxx(&511B0dc9J5u>B}mew{gW z7^mbGu*n_zDZL8V?hZqh>KEA`9a_pCu+WaJlu-@P|ODRifR|%5;=D|OGX()%LSX?wtZ}OukhqI9inEz->Hm*V~v(U`g1_pXikYpSko`i z<~KoQx{+`K`~^m8(G+BaI_qs>p1qqY9rm$yy_*HDLHD~%!}kn^r+AFE7GJaJy`z+U zd)bSE`EQOVbxXC>BEO+3i85o9FtZOPy?SOEa@3<0soa ze~4`J)9*#rHoqwZur$pwC=(`*>2V>u(FqNPyUp+Z9wd3{`(=1WB}T+_x=u|IWAi&k z5-5G66AGuDCz{c`Jj1*^)0jVKiOuh0iiumEndNHp8@kVxk}ZQGS$Lm`uIVr=Ve%PP z(5IDGk~=j=xiNpR-n!onEav`v6P9Og!v5={ZT$R5HPwRDZGSS~zO7ux?#C=N;U??b zcSPv>;i83-YS2JQoop%QXRXHkk>y5pYNx|ge_U+MwrvmAdd(tEM~~($Og9x zo2@EVjdvnqqz8zt)Cj6P>obkm`~8|JE;{yAKR=U6OC~s3j9PPQ1&pk)>QG*z#lzAk z(416Z>EmloLOpaD-CmY*<1@lA#b<>XEt&xc8>bnab60fGOWB?n5+QGs+!d=17FaXR z+H4kGchFZ~%t|p@`~oiX1r27kWM$&y4 zRP^}a6hzN3q~xboq~vQ#DU1rX9`+_4Y}dnTOP@w4L2mpJgWYHb<@Jp=%_J+Jc`P(r zkDMV(o(G?-PO)gFK_Gcrf`irnma6Nh8H_xz~{y`=ubSu#pjh1yP8IwfH5(uq4n+e(R zG&3X&$0QJwyEKzj(O}OSNr7yS6JTH<|MLp{4la_UxPF<4r5V9{LGFT>m~6N5K~a%2eux{oL}uDq8(=40}Sp~=T+9-}v!GXv3a zzYGy2Oo}mD9vCgj22_e?-WDh|=02yFJoED5P3rV8#hhJYw8-dUB`Nty61y@W#xw~v zZawjd%~p*Ug02SBjdc*Fiu3)ot}wjX2az5`*-R9T^(&+$bhK6dLAK;;%Bb(4+ol`M zSrHk=eC|uyV$4rMDX2G_vmc=m%V;)BxA|@0^rS~FYR+nuqd(l zoqoCQeY6*T%r!>KC0m--Q=cSxdZE;w`c%EAS4u>zr+%ct(`y91)&@r!&66V4Li5}_ z^_IimCFn{C+8;1)qdQ{>tGh-s zht41I)>qNPU^mjKtMT+RNNbHWm0Vd4GKq;dGHWy>kr@Wpu$&}bD z6MQM>)1)0JCiqmrUkbiOcK}q-)`12IF~1X)rphl(J5}9-!R>TWEzr~xHXD}y<_Qtn z(U?UHx$#faCdHT^Z=}2|UvN8n*4h~-lzH=fuUZwdbK*Ocd3)8)MKGXIt(~#L&b
I!Z5Nc9GO|4JxRt5fgq}n3euMIslx5X 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

wb?nHM}O%Eh3LK4v&fXaNVE7 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 QiuM)nD>-&+mfS-AKa=Jbf&c&j diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h index 2606a62..7f04629 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h @@ -54,8 +54,30 @@ template class Buffer { public: - Buffer() {} - ~Buffer() {} + Buffer() + { + } + + Buffer& operator=(const Buffer& other) + { + if (&other == this) return *this; + + value_.reset(); + size_ = 0; + ExpandIfNeeded(other.size_); + memcpy_s(value_.get(), size_, other.value_.get(), other.size_); + + return *this; + } + + ~Buffer() + { + } + + bool Empty() const + { + return !value_; + } void ExpandIfNeeded(UINT size) { diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp index 852efc6..873de69 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp @@ -3,7 +3,6 @@ #include "Duplicator.h" #include "Monitor.h" #include "Device.h" -#include "Common.h" #include "Debug.h" #include "IUnityInterface.h" @@ -213,30 +212,30 @@ bool Duplicator::Duplicate() { // If any monitor setting has changed (e.g. monitor size has changed), // it is necessary to re-initialize monitors. - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST."); + Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST."); state_ = State::AccessLost; break; } case DXGI_ERROR_WAIT_TIMEOUT: { // This often occurs when timeout value is small and it is not problem. - // Debug::Log("Monitor::Render() => DXGI_ERROR_WAIT_TIMEOUT."); + // Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_WAIT_TIMEOUT."); break; } case DXGI_ERROR_INVALID_CALL: { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL."); + Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL."); break; } case E_INVALIDARG: { - Debug::Error("Monitor::Render() => E_INVALIDARG."); + Debug::Error("Duplicator::Duplicate() => E_INVALIDARG."); break; } default: { state_ = State::Unknown; - Debug::Error("Monitor::Render() => Unknown Error."); + Debug::Error("Duplicator::Duplicate() => Unknown Error."); break; } } @@ -252,19 +251,19 @@ bool Duplicator::Duplicate() { case DXGI_ERROR_ACCESS_LOST: { - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST."); + Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST."); state_ = State::AccessLost; break; } case DXGI_ERROR_INVALID_CALL: { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL."); + Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL."); break; } default: { state_ = State::Unknown; - Debug::Error("Monitor::Render() => Unknown Error."); + Debug::Error("Duplicator::Duplicate() => Unknown Error."); break; } } @@ -289,8 +288,115 @@ bool Duplicator::Duplicate() { std::lock_guard lock(mutex_); - lastFrame_ = Frame { copyTarget, frameInfo }; + lastFrame_.texture = copyTarget; + lastFrame_.info = frameInfo; } + UpdateMetadata(); + return true; +} + + +void Duplicator::UpdateMetadata() +{ + metaData_.buffer.ExpandIfNeeded(lastFrame_.info.TotalMetadataBufferSize); + if (!metaData_.buffer.Empty()) + { + UpdateMoveRects(); + UpdateDirtyRects(); + } + + { + std::lock_guard lock(mutex_); + lastFrame_.metaData = metaData_; + } +} + + +void Duplicator::UpdateMoveRects() +{ + metaData_.moveRectSize = metaData_.buffer.Size(); + + const auto hr = dupl_->GetFrameMoveRects( + metaData_.moveRectSize, + metaData_.buffer.As(), + &metaData_.moveRectSize); + + if (FAILED(hr)) + { + switch (hr) + { + case DXGI_ERROR_ACCESS_LOST: + { + Debug::Log("Duplicator::UpdateMoveRects() => DXGI_ERROR_ACCESS_LOST."); + break; + } + case DXGI_ERROR_MORE_DATA: + { + Debug::Error("Duplicator::UpdateMoveRects() => DXGI_ERROR_MORE_DATA."); + break; + } + case DXGI_ERROR_INVALID_CALL: + { + Debug::Error("Duplicator::UpdateMoveRects() => DXGI_ERROR_INVALID_CALL."); + break; + } + case E_INVALIDARG: + { + Debug::Error("Duplicator::UpdateMoveRects() => E_INVALIDARG."); + break; + } + default: + { + Debug::Error("Duplicator::UpdateMoveRects() => Unknown Error."); + break; + } + } + return; + } +} + + +void Duplicator::UpdateDirtyRects() +{ + metaData_.dirtyRectSize = metaData_.buffer.Size() - metaData_.moveRectSize; + + const auto hr = dupl_->GetFrameDirtyRects( + metaData_.dirtyRectSize, + metaData_.buffer.As(metaData_.moveRectSize /* offset */), + &metaData_.dirtyRectSize); + + if (FAILED(hr)) + { + switch (hr) + { + case DXGI_ERROR_ACCESS_LOST: + { + Debug::Log("Duplicator::UpdateDirtyRects() => DXGI_ERROR_ACCESS_LOST."); + break; + } + case DXGI_ERROR_MORE_DATA: + { + Debug::Error("Duplicator::UpdateDirtyRects() => DXGI_ERROR_MORE_DATA."); + break; + } + case DXGI_ERROR_INVALID_CALL: + { + Debug::Error("Duplicator::UpdateDirtyRects() => DXGI_ERROR_INVALID_CALL."); + break; + } + case E_INVALIDARG: + { + Debug::Error("Duplicator::UpdateDirtyRects() => E_INVALIDARG."); + break; + } + default: + { + Debug::Error("Duplicator::UpdateDirtyRects() => Unknown Error."); + break; + } + } + return; + } } \ No newline at end of file diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h index 86673a2..9330909 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h @@ -7,6 +7,8 @@ #include #include +#include "Common.h" + class Monitor; @@ -32,10 +34,18 @@ class Duplicator public: using State = DuplicatorState; + struct Metadata + { + Buffer buffer; + UINT moveRectSize = 0; + UINT dirtyRectSize = 0; + }; + struct Frame { Microsoft::WRL::ComPtr texture; DXGI_OUTDUPL_FRAME_INFO info; + Metadata metaData; }; explicit Duplicator(Monitor* monitor); @@ -52,7 +62,11 @@ private: void InitializeDevice(); void InitializeDuplication(); void CheckUnityAdapter(); + bool Duplicate(); + void UpdateMetadata(); + void UpdateMoveRects(); + void UpdateDirtyRects(); Monitor* monitor_ = nullptr; State state_ = State::Ready; @@ -64,4 +78,6 @@ private: volatile bool shouldRun_ = false; std::thread thread_; mutable std::mutex mutex_; + + Metadata metaData_; }; diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp index bdad7be..ee0d732 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp @@ -67,9 +67,9 @@ void Monitor::Initialize( void Monitor::Render() { - const auto frame = duplicator_->GetFrame(); // copy + const auto& frame = duplicator_->GetFrame(); const auto texture = frame.texture; - const auto frameInfo = frame.info; + const auto& frameInfo = frame.info; if (!texture) return; @@ -100,8 +100,6 @@ void Monitor::Render() } } - UpdateMetadata(frameInfo); - if (frameInfo.PointerPosition.Visible) { GetMonitorManager()->SetCursorMonitorId(id_); @@ -129,102 +127,6 @@ void Monitor::UpdateCursor(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) } -void Monitor::UpdateMetadata(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) -{ - metaData_.ExpandIfNeeded(frameInfo.TotalMetadataBufferSize); - UpdateMoveRects(frameInfo); - UpdateDirtyRects(frameInfo); -} - - -void Monitor::UpdateMoveRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) -{ - moveRectSize_ = metaData_.Size(); - - const auto hr = GetDeskDupl()->GetFrameMoveRects( - moveRectSize_, - metaData_.As(), - &moveRectSize_); - - if (FAILED(hr)) - { - switch (hr) - { - case DXGI_ERROR_ACCESS_LOST: - { - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST (GetFrameMoveRects())."); - break; - } - case DXGI_ERROR_MORE_DATA: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_MORE_DATA (GetFrameMoveRects())."); - break; - } - case DXGI_ERROR_INVALID_CALL: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL (GetFrameMoveRects())."); - break; - } - case E_INVALIDARG: - { - Debug::Error("Monitor::Render() => E_INVALIDARG (GetFrameMoveRects())."); - break; - } - default: - { - Debug::Error("Monitor::Render() => Unknown Error (GetFrameMoveRects())."); - break; - } - } - return; - } -} - - -void Monitor::UpdateDirtyRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) -{ - dirtyRectSize_ = metaData_.Size() - moveRectSize_; - - const auto hr = GetDeskDupl()->GetFrameDirtyRects( - dirtyRectSize_, - metaData_.As(moveRectSize_ /* offset */), - &dirtyRectSize_); - - if (FAILED(hr)) - { - switch (hr) - { - case DXGI_ERROR_ACCESS_LOST: - { - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST (GetFrameDirtyRects())."); - break; - } - case DXGI_ERROR_MORE_DATA: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_MORE_DATA (GetFrameDirtyRects())."); - break; - } - case DXGI_ERROR_INVALID_CALL: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL (GetFrameDirtyRects())."); - break; - } - case E_INVALIDARG: - { - Debug::Error("Monitor::Render() => E_INVALIDARG (GetFrameDirtyRects())."); - break; - } - default: - { - Debug::Error("Monitor::Render() => Unknown Error (GetFrameDirtyRects())."); - break; - } - } - return; - } -} - - int Monitor::GetId() const { return id_; @@ -341,25 +243,29 @@ int Monitor::GetHeight() const int Monitor::GetMoveRectCount() const { - return moveRectSize_ / sizeof(DXGI_OUTDUPL_MOVE_RECT); + const auto& metaData = duplicator_->GetFrame().metaData; + return metaData.moveRectSize / sizeof(DXGI_OUTDUPL_MOVE_RECT); } DXGI_OUTDUPL_MOVE_RECT* Monitor::GetMoveRects() const { - return metaData_.As(); + const auto& metaData = duplicator_->GetFrame().metaData; + return metaData.buffer.As(); } int Monitor::GetDirtyRectCount() const { - return dirtyRectSize_ / sizeof(RECT); + const auto& metaData = duplicator_->GetFrame().metaData; + return metaData.dirtyRectSize / sizeof(RECT); } RECT* Monitor::GetDirtyRects() const { - return metaData_.As(moveRectSize_); + const auto& metaData = duplicator_->GetFrame().metaData; + return metaData.buffer.As(metaData.moveRectSize); } diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h index 5346f0c..99a8cb2 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h @@ -54,9 +54,6 @@ public: private: void UpdateCursor(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); - void UpdateMetadata(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); - void UpdateMoveRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); - void UpdateDirtyRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); void CopyTextureFromGpuToCpu(ID3D11Texture2D* texture); int id_ = -1; @@ -77,8 +74,4 @@ private: ID3D11Texture2D* unityTexture_ = nullptr; Microsoft::WRL::ComPtr textureForGetPixels_; Buffer bufferForGetPixels_; - - Buffer metaData_; - UINT moveRectSize_ = 0; - UINT dirtyRectSize_ = 0; };