(Hogy a .......)Grafikus memória direkt címzése. (Szóval overlay)

Fórumok

Sziasztok.

A címben megadott témában kellene valami jó kis doksi. (A Google a barátom tudom, de jelenleg cserbenhagyott) Az igazi az lenne ha C alapok lennének de jó asm és c++ is. Írtam egy képelemző programot, és az vele a gáz, hogy a proci akkor is 40-50%-on megy ha csak dobja a video-t. Szóval igen komoly sebességnövekedést érnék el egy direkt memória címzéssel.
Ja és linux alá természetesen.
Előre is köszönöm.

Szerk:
A fene gondolt erre vacak a kamera kernelmodulja. Na mindegy a lényeg, hogy megoldódni látszik a probléma, ugyanis akármivel nézem ezt a kamera képet azzal is 40-50%-on eszi a gépet. Rászurtam egy másik (típusú) kamerát a gépre és azzal gyönyörűen kb 3-6%-on eszi a gépet. Szóval megszivattam saját magam.Azért köszönöm a segítséget.

Hozzászólások

Valós / Védett módban? VESA-ban? milyen felbontással/színmélységgel?

640*480 nvidia kártya (nem kell hogy hordozható legyen a kód, ezen az 1 gépen kell futnia). A valós vagy védett az mindegy, ahogy könnyebb megvalósítani. (ASM ben nem vagyok nagy ász sajnos egyenlőre). Ja és a színmélység az gyak tetszőleges az lenne, lejobb ha 256 szintű fekete fehér lenne.

ah látom linux alá kellene. Nem hiszem, hogy a kernel hagyná, hogy Te csak úgy "belepiszkálj" a memóriába.
Ha jól tudom, az MPlayer tud ilyet: http://svn.mplayerhq.hu/mplayer/trunk/libvo/vesa_lvo.c?revision=27541&v…

A 640*480 -esből a VESA 256-szinüt(1byte/pixel) támogat. (ez a 0x100 -as)

Látod az opengl eszembe sem jutott. Lehet az is elég lenne csak az van hogy openglt nem tanultam soha. (Az az igazság, hogy én nem is programozó vagyok hanem fizikus, csak magamtól megtanultam C-programoznizni és ASM-ezni amiennyi nekem kellet) de nem rossz ötlet az opengl. Amennyi nekem kell az biztosan nem sok. Megnézem ezt a könyvet.

az fb dev-en keresztul valahogyan tudod mmap-elni a framebuffer-t
xorg is ezt csinalja

--
When in doubt, use brute force.

Én DGA-val nyúlnék a dologhoz első közelítésben.

> Sol omnibus lucet.

miben segit az /usr/include/asm ? nem hiszem, hogy attol hajlando lenne nalam az SDL dga-t hasznalni.

amugy most kiprobaltam az mplayer -vo dga-t, attol lehalt az X ugy, hogy ujra se lehetett inditani (nem volt tobbet kep). szoval driver fuggo lehet a dga hasznalhatosaga (pl. nvidia-ra is azt irtak, hogy nem megy - nekem mondjuk ati fglrx van), de talan az opensource driverekkel megy.

- Use the Source Luke ! -

Amúgy assembly-hez nem kell ma már nyúlni (speciális eseteket kivéve). Egy jól megírt C++ program hozza a megfelelő sebességet, mégis magasabb szintű, mintha direkt opkódokat írnál :)

--
Kinek nem inge, ne vegye gatyára

Hát nem tudom. Én meg azt olvastam sokszor, hogy az asm és a C közöt is egész komoly tempókülömbségek vannak (akár 2-3*-os is, lehet nem igaz, de ilyen utalások voltak). Ami kérdéses, hogy mennyit nyer vele az ember mert jóval lassabban lehet kifejleszteni így a kódot, és így summa lassabban lehet kész az eredmény.

Vegyük egy átlagos fejlesztő C tudását 1-nek.

Egy komolyabb fejlesztő aki kicsit is odafigyel a hatékonyságra, gyorsabb kódot ír: 1.5-2

Ehhez képest asm-ben, mély tudással az adott processzorrol: 2-5 (x86 esetén inkább 2-3).

Persze ez nem azt jelenti, hogy a C kódot egy az egyben megírod asm-ben, annál még a Gcc is jobb kódot generál. Ilyenkor már utasítások sorrendjét kell variálni, ciklusokat "kicsomagolni" (loop-unrolling), stb. Ezek egyrésze C-ben is működik, nagy része pedig mély tudást feltételez a processzor működéséről.

Amíg ez a tudás nincs meg, bőven jó a C, ha gyorsítani akarsz, SSE-nek nézz utána...

(Mind az intel, mind az amd honlapján vannak ilyen témájú leírások, a leírások elején általános (C-s) trükkök, később specifikusabb ötletek. Plusz mindkét cégnél vannak profiler szoftverek.)

Egyébként "a korai optimalizáció a legtöbb baj forrása".
Tehát írd meg C-ben, profiler programokkal, saját mérésekkel keresd meg a leglassab részt, módosíts az algoritmuson ha lehet (itt vannak nagyságrendbeli gyorsítási lehetőségek), optimalizáld C-s trükkökkel, SSE, asm.
Állj meg, ha elég gyors. :)
Asm-től ne várj csodákat...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Vagy én nem értem amit mondasz, vagy te nem érted a 80-20-as szabályt. :)

A szabály arról szól, hogy egy átlagos programnak vannak olyan részei amik ritkán futnak, és vannak olyan részei, amik gyakran.
Azaz a program 20%-a fut az idő 80%-ában.

Ebből következik, hogy semmi értelme az egész programot optimalizálva írni, elég azt a bizonyos 20%-ot.

(De ez a 20% nem mindig az, amit mi annak gondolunk. Ezért érdemes először szépen tisztán kódolni, mérni, majd ezután optimalizálni.)

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Én régebben SDL-t használtam ilyen célra, mert nagyon praktikus, hogy lehet állítani, milyen API-t használjon maga alatt.
Simán lehet fejleszteni X alatt, aztán a végeredményt futtathatod akár framebufferen is.

Nem ertek hozza, de szerintem ha egy folyamatosan valtozo _kepet_ akar kirajzolni, azt OpenGL-lel csak ugy tudja megtenni, ha folyamatosan feltolti texturakent, ami minden, csak nem gyors. (Annyi elonye lehet, hogy a driverben jobban meg lehet irva ez a feltolto resz, esetleg DMA-t is hasznalhat, nVidia kartyan, nem tudom.) Az SDL meg megintcsak lassu, konkretan. Nem kicsit, nagyon.

Amennyire en tudom, Linuxon nincs normalis modszer a videomemoria kozvetlen eleresere, ami mezei userkent is megy, es rendesen interaktal ilyen nagyobb rendszerekkel mint az X11 es tarsai. Kozvetlen durrbele hekkek es framebuffer magiak persze vannak, de azokra sokminden eszembe jut, csak az nem, hogy szep megoldas...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Nem feltetlenul, azert mindenre van megoldas, es Linuxra is lehet viszonylag gyors videokezelest irni, de ilyen konkretan pont nincs, hogy visszakapod egy memoriaterulet cimet, es oda renderelsz, es az egybol latszik a kepernyon is, a'la VGA $A000:0000. :) Mivel nem tudjuk jelenleg milyen modszert hasznalsz, milyen a kod, es az mit csinal, mig 40-50%-ot visz, ez a 40-50% mekkora kepet, milyen szinmelysegben es foleg: milyen gepen es milyen framerate-tel jelent, ezert eleg nehez tippeket adni. Ezzel csak azt akartam mondani, hogy nem hiszek a fenti "hasznalj SDL-t" meg "hasznalj OpenGL-t" varazsmodszerekben. Foleg mert lattam mar SDL kodot, amit sajat kezuleg gyorsitottam haromszorosara (ami meg mindig lassabb volt mint kene, de azert eleg latvanyos valtozas volt), tovabbra is csak SDL hasznalataval... Mindenben lehet lassut es gyorsat is irni...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Egyebkent, peldaul, azt irod, visszaolvasva, hogy 640x480 fekete-feher kepet akarsz kirakni. Tulajdonkeppen a blittelo rutinok sebesseget meghatarozza szinte minden rendszeren, hogy kell-e kozben szinmelyseg-konverziot vegezni. Ha pl. egy truecolor-ba allitott videokartyara renderelsz egy 256 szinu palettas kepet, akkor az lehet, hogy nem lesz gyors. Viszont ha ugyanannak a blittelo X11 vagy barmilyen mas fuggvenynek egy olyan szinmelysegu (es pixelformatumu! nem mindegy hogy BGRA vagy ARGB peldaul) buffert adsz, mint a kepernyo, akkor lehet hogy 40-50% helyett 1-2% procival fogja elvegezni a blittelest. Csak tipp, de ki kellene probalni. Ilyenkor ugyan neked kell konvertalni, de akkor bevethetsz mindenfele assembly magiat, es megirhatod gyorsra, nem vagy a driver/X11 kodjara, es annak potencialis lassusagara utalva. Ilyesmi jut eszembe elsore...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Az eddigi megoldásom unicap-imaging könyvtárát használja. Roppant egyszerű, de vele együtt iszonyú lassú is. megnézem hogy találok e más módszert, de itt nagyon sok jó tanácsot kaptam biztosan találok valamit közöttük. Ez az sdl, és OpenGL annyira egyszerűnek tűnik ami nekem kell az egészből, hogy ezeket kipróbálom, ha nem jön be keresek tovább. De köszönöm szépen az ötletet.

Azt nem vágom, hogyha írsz egy akármilyen feldolgozó algoritmust, akkor pixelenként eleve elhasználsz pár száz vagy ezer órajelet a pixel értékének kiszámításához. Ahhoz képest, hogy userspace memóriában állítod össze a képet és a driver másolja a videokártyára, mindössze egy másolást tudsz megspórolni azzal ha eleve a videokártyára írod. Ráadásul ez egy folytonos címtartományról folytonos címtartományra másolás amiket általában a hardver eléggé hatékonyan megold.

Tehát értelmes becslés szerint maximum pár százaléka lehet a teljes terhelésnek, amit meg tudnál ezzel a trükkel spórolni. Inkább vegyél egy erősebb gépet néhány tízezerér azt kész.

Tehát értelmes becslés szerint maximum pár százaléka lehet a teljes terhelésnek, amit meg tudnál ezzel a trükkel spórolni.

Az elmelet ott bukik, hogy valoszinuleg szinmelyseg-konverzio is tortenik a blitteles kozben, es ezert lassu, tehat innentol sem linearis teruletekrol, sem hardveres masolasrol nem beszelhetunk. Lasd fent.

Inkább vegyél egy erősebb gépet néhány tízezerér azt kész.

Es igy keletkeznek a slideshow-nezegetok, aminek 4 magos proci es masfel giga RAM kell, maskepp beszaggat. Igaz C64-re meg lehetne irni, de inkabb vettek erosebb hardvert! Szanalmas.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Én is inkább azon gyanakszom, hogy ez az én hibám. Valamit nem gondoltam át megfelelően stb. A Gép egyébként nem egy erőmű p4 2.2 celeron, de nem létezik, hogy ennyire ne bírna egy ilyen egyszerű feladatot. És még a matek modul nem is megy. Az mplayer meg röhögvel lejátszik rajta bármilyen agyontömörített filmet, egy sima "webkamerakép" megjelenítése meg eszi 50%-al a procit. Ez nem a vas hibája.

Ez bizony nem...

Win alatt .Net-tel és Qt-val is csinálok hasonlót, mindkettőben a beépített képmegjelenítőt használva (azaz a webcam képét még át is kell alakítanom BGR-ről RGB-re, és a sorokat is fel kell cserélni), még egy 1.6-os laptopon sem érem el az 5%-ot... (Igaz 320x240, kb 15fps.)

Valamit tuti elrontasz.
(Egyébként OpenCV-t ismered? Szerintem az kéne neked...)

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Sose láttam... Ettől még lehet jó.

Ahogy nézem erőssége inkább a capture. De gyanus, hogy nem a lib hibája a sebességgondod...

OpenCV eléggé de facto szabvány a maga területén, elsősorban gépi látás területéhez kapcsolódo algoritmusok vannak benne. (Az élkiemeléstől az objektumkeresésig.)
Van minimális capture, és megjelenítő api, annyi amennyi az ilyen feladatokhoz elég. Sebesség gondok viszont tuti nincsenek vele.

Eszembe jutott valami: biztos csak az új frame-eket rajzoltatod ki?
Nem lehet, hogy akkor is küldöd a frame-eket, amikor nincs is új?

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

most nem azert de a 640x480@30fps pont nyolcszorosa savszelessegben a 320x240@15fps-nek, es 5%*8=40%.
amugy a webkamera kep megjelenitesenek sebessege nem mervado, mert az valoszinuleg yuv szinterben jon be es rgb-ben megy ki, a szoftver konverzio meg marha lassu. ha a szoftverkonverzio volt a gond, akkor SDL-lel konverzio nelkul (lasd SDL_ANYFORMAT flag az sdl_setvideomode-nak, de yuv-ot nem tud) eleg gyors lesz. ha ugy is lassu, akkor xvideo-val lehet megprobalni - csak az bonyolultabb -, mert bar az yuv szintert fogad es nem a rgb-t, a szurkearnyalatot nagyon egyszeru yuv-ban reprezentalni, hiszen az Y komponens a fenyerosseg (azaz arnyalat 0 es 255 kozott), az U meg V pedig 128 (vagy 127 vagy 0?), es akkor pont szurket kapunk.
es persze mint fentebb irtam lehet probalkozni a DGA-val rootkent, akar SDL-en keresztul is, de az lehet, hogy tenyleg nem a legszebb megoldas, ha egyaltalan mukodik.

- Use the Source Luke ! -

Ha mar itt tartunk, biztos, hogy a megjelenites viszi az idot? :) Nem lehet, hogy fos a webcam driver, es a kep gepbe juttatasa zabal ennyit? :)

Szerk: haha, es ebben a pillanatban frissult a topic cime. Igy legyen otosom a lotton! :)

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Hát hallod mit össze szivattam magam :) Teljesen jól megy. Egy másik kamerával. Az ami nekem van (ergo a rossz) valami ucv drivert használ, és eddigi tapasztalatom alapján ez okozta a bajt. Ez meg valami kernelszinten támogatott ov51x vagy mi. Na a lényeg hogy HASÍÍÍÍÍT. :) :) :) :)

De most gomolyan, 2.2-es Celeron nagyságrendileg 6000 MIPS.

640*480*30= 9,2 m

Ne tartson már 600 órajelig 1 pixel konvertálgatása és másolgatása, hogy a képernyőre kerüljön.
Vegyük már észre, hogy egy ilyen gép röhögve lejátszik egy 720p-s DivX-et, DGA nélkül...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

http://en.wikipedia.org/wiki/Million_instructions_per_second#Timeline_o…

2.2 Ghz az eleve 2000 MIPS, de ugye a Pentium Pro óta túlvagyunk az 1 utasítás/órajelen...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Ezt hívják MIPS-nek... Egyébként nem elméleti (az ennél több lenne) SPECint-tel mérik...

Nyilván tudok olyan kódot írni, ami alatt a proci folyamatosan a memóriára vár...

De azért 600 órajel nekem elég soknak tűnt ahhoz, hogy ne fogjuk konvertálgatásra és másolgatásra...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Az XV mint olyan? azt hasznaljak a filmlejatszo progik is, optimalis esetben, X alatt legalabbis effektivebb, mint a sima nativ x+bufferele's. Es van egy rakat kvazi hardveresen tamogatott trafo is melle' (colormap-ek kozotti valtozgatas, yuv-trafok, nagyitas). libxv-dev. lehet hogy vki mar javallotta, ha wronly voltam akkor bocs.