ubuntu 12.0.4, alsa+darkice: buffer overrun!

Fórumok

Adott egy linuxos streamer, ahol mostanában elkezdett a darkice makrancoskodni, a default 5mp-es bufferméret kevés lett, az adás akadozott, emiatt megnöveltem a bufferméretet 60mp-re. Így már nem akad, órákig stabil, de kb. félnaponta reconnecttel, előtte másodpercenként többtíz BufferedSink-üzenet után pár Buffer overrun!-bejegyzést biggyeszt a logba.
Találtam hasonló problémákat a neten, de megoldást nem nagyon. Valakinek van tippje esetleg?

darkice v1.0-1
alsa v1.0.25-1
kernel 3.2.0-76-generic-pae

Hozzászólások

Nekem már az sem teljesen világos, hogyan történik a stream-elés. Van a hanganyag, valamilyen mintavételi frekvenciával. Ezt hálózaton áttolják, eddig akár érthető is. És most? Valahány hangmintánként van hozzá időbélyeg, s a kliens oldalon újramintavételezik? Vagy csak átadják lejátszásra natívan, s ami a stream szerver és a kliens mintavételi frekvenciáinak hibájából származik, amiatt hízik szép lassan a buffer, vagy a másik irányban pedig buffer underrun lesz? Netán néha beszúrnak egy-egy mintát, hogy ne legyen alulcsordulás? Vagy kivesznek egy-egy mintát a túlcsordulás megakadályozására?

Csak azért érdeklődöm, mert szerintem nem triviális a probléma, hiszen a szerver és a kliens nem azonos órajelről, nem mereven azonos időzítésről, azaz nem szinkronban járnak.

Előre felvett anyagnál persze nem probléma, mert a kliens tud ütemezni, de élő stream esetében érdekesebb ez.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem megerteni, hanem zavarmentesen uzemeltetni szeretnem! :)
Volt kozben egy levelvaltasom az egyik fejlesztovel, szerinte ez a hiba tipikusan azert van, mert a gep le van maradva a kodolassal (lagol), ennek oka valamilyen tulterheles lehet. Sajnos ilyen terhelest nem tudtam detektalni se hardver, se szoftver oldalon. Mivel a gepre a rendszerfrissiteseken kivul mas nem kerult, ezert inkabb arra gyanakszom hogy valamilyen rendszerkomponens valtozott, amitol osszeferhetetlenseg lett a darkice regi verziojaval.

--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

Elhiszem neked. :) A probléma felvetésével arra utaltam, hogy a buffer alul- vagy túlcsordulás akár a normális működés része is lehet attól függően, hogy ez ellen tesznek-e valamit, vagy sem. Mert a dologban kapásból ott rejtőzik, hogy nem azonos sebességgel írjuk és olvassuk a buffereket.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

a buffer overrun az a jelenség amikor a gép képtelen olyan ütemben csomagolni az adatot, amilyen ütemben az érkezik, és emiatt időben komplett szakaszok esnek ki az adatfolyamból, gyak. szól a stream aztán egyszer csak anélkül hogy szünet lenne, kihagy egy ütemet a zene, kimarad egy szó egy szöveges tartalomból, stbtb.

--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

Meg lehet az is, amit írtam: a capture és a play mintavételi frekvenciája minimálisan eltér, miközben azt hiszi a rendszer, ezek azonosak. Ekkor előállhat az, hogy noha ráér mindkét gép, bőven van futásidőben tartalékuk, egész egyszerűen lassabban írjuk a buffert, mint olvassuk azt. Nyilván erre a problémára megoldás lehet a resampling akár, csak azt mondom, megoldástól függ, hogy előállhat-e ez a probléma.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ez miért is a Linux bűne? Van két vasam, aszoinkron órajelről járnak, de a valós életben ugyanúgy telik az idő. Ez technikai probléma. Vagy szinkron órával kell rendelkezni, vagy aszinkronnal ugyan, de iszonyú pontossal - atomóra -, vagy át kell vinni a hálózaton időbélyegeket, felcímkézni egyes hangmintákat, hogy azok milyen időponthoz tartoznak, kiszámítani, hogy adott időtartam alatt hány hangminta jött át, s újramintavételezni az egészet úgy, hogy az adott idő alatt éppen annyi hangmintát használjunk fel, amennyit a capture küldött, de annyit játsszunk le, amennyit a player órája diktál. Ez nem oprendszertől függ, sokkal inkább az alkalmazás speciális, hiszen a két gép órája között egészen pontosan nulla eltérés megengedett. A resamping során valamiféle interpoláció kell, ilyet csinál például a pulseaudio is. Persze sanszos, hogy a pulse-t ilyen minimális frekvenciakülönbségű újramintavételezésre nem nagyon lehet rábeszélni, persze nem biztos. Sőt, lehet, mégis tudja, hiszen épp a pulseaudionak van hálózati interface-e.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

nem a linux baja hanem (az enyém :)) a szedett vetett drivereknek.
egyébként valamit félreértesz, itt nem két vas van, hanem van egy hangkártyabemenetre dugott analóg jel, amit a hangkártya adc-ja konvertál majd ez a jel a driverben beállított bufferelés után továbbítódik a streamszerver felé. mitől változik meg a buffer telítettség? hol akad el a folyamat ha látszólag nincs semmilyen hardverkomponens még a negyedére sem leterhelve (kellő tartalékkal rendelkező hardverről van szó).
--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

Épp erről beszéltem eddig. Nem kell semminek sem leterhelve lenni, pusztán picit eltér az írás és olvasás átlagos sebessége, s vagy a végtelenségig hízik a buffered, vagy annyira lesoványodik szegény pára, hogy a végén elfogy. :) És ehhez egyáltalán nem kell rossz driver.

Ugyan nem tudom, de gondolom, a streamer olyan ütemben falja a buffer tartalmát, ahogy tőle eszi a kliens. Csak az a gond, hogy a hangkártya mintavételezése meg nincs ezzel szinkronban, lévén, az egyik kvarc Kecskeméten, a másik meg Mátészalkán határozza meg az ütemezést.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ha ez lenne az ok, akkor feltetelezem hogy mivel az atviteli savszelesseg, bitrata stb. allando, ezert a hiba is periodikusan ismetlodo lenne. Ezzel szemben van hogy masodpercenkent dobal egyet, van hogy orakig semmi hiba.

--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

Nyilván a valós okot nem tudom, csak azért vetettem fel a gondolatot, mert már magam is eltűnődtem azon, milyen lenne valós idejű hangot hálózaton átvinni, s arra a következtetésre jutottam, hogy nagyon nem triviális. Mert milyen egyszerűnek tűnik, hogy mintavételezem, átviszem, lejátszom, csak hát az órajelet nem viszem át, innentől kezdve már izgalmasabb a dolog.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Minek orajelszinkron? Van ket edenyed, az egyikre alul egy kis lyuk van furva, amibol folyamatosan folyik a viz a palantakra. A feladat hogy a viragagyas folyamatosan es egyenletesen ontozve legyen. Ehhez nem kell mast tenni mint a tartalyt rendszeresen tolteni - mindegy hogy milyen sebesseggel, mindegy hogy milyen surun, az a lenyeg hogy gyorsabban toltsd tele mint ahogy kiurulne. Az orajelet a kis lyuk biztositja.

Nalam most jelenleg az a helyzet hogy olyan gyorsan telik a tartaly, hogy neha tulcsordul a peremen, igy nem jut el a teljes mennyiseg a kis lyukon keresztül a palantakhoz, hanem egyszeruen karbavesz. :)

--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

Most érzem, hogy kezdettől fogva nem érted, mit mondtam. :(

Van az analóg hangunk. Mintavételezed mondjuk 44000 Hz-cel. Igen, 100 Hz-cel kevesebbet írtam, mint a nominális érték, nem elgépelés. Tehát van 44000 hangmintád minden másodpercben. Ezt áttolod a hálózaton, van ott egy hangkártya, amelyik 44200 Hz-cel mintavételez, ilyen tempóban olvassa ki a bufferedet. Ha épp egy másodpercnyi hanganyagod, azaz 44000 mintád volt a bufferben, ekkora sebességgel lejátszva 995.475 ms alatt felfalja a lejátszó hangkártya azt a hanganyagot, amelyet az input oldalon 1 másodperc alatt készítettek. Tehát 4.52 ms-nyi hanganyag eltűnik látszólag. Azért látszólag, mert nem tűnt el, csak gyorsabban játszottuk le. Igen, csak ugye az anyag valós időben keletkezik, s hacsak nem egy fekete lyuk határán egyensúlyozunk, akkor feltételezhetjük, hogy az idő egyformán telik a capture és a play helyén.

Az előbbi feltételezésekkel, ha jól számolom, 221 másodpercenként egy teljes másodpercnyi hanganyag „tűnik el” a bufferből, tehát, ha a buffered éppen 1 másodperc hosszú, akkor 3 perc 41 másodpercenként tapasztalhatsz buffer underrun-t, ennyi időnként fog elakadni a lejátszás, s 1 másodpercig néma lesz, míg megint megtelik a buffered.

Nyilván nem azt állítom, hogy a probléma megoldhatatlan. Például át lehet vinni időbélyegeket egyes hangminták mellé, ebből a vételi oldalon ki lehet számítani, hogy az adott minták mennyi időre elegendők, s lehet interpolálgatni, újramintavételezni az egész hanganyagot, s így eltérő mintavételi frekvencia esetén is pontos lesz a lejátszás sebessége. Mivel rendre újra kiszámoljuk az újra mintavételezést, a kvarcok frekvenciájának driftje sem okoz gondot.

Vagy át lehetne vinni az órajelet, de ehhez jó hosszú madzag kell. :) Meg aztán lehet mindkét helyen atomórát használni.

Analóg példa: van egy magnód, amelyik szalagra veszi a hangot, majd ezt a szalagot mondjuk némi szalagvezető mechanikán átvezetve lejátszó fej és szalaghúzó mechanika elé vezeted. Ha picit gyorsabb a lejátszásod, a felvétel és lejátszás közti szalagod egy idő után elfogy, a szalag elszakad. Ez a buffer underrun esete.

Ha a lejátszás lassabb, akkor a felvétel és a lejátszás között egyre több szalag halmozódik szép lassan, de feltartóztathatatlanul.

Átmenetileg lehet gyorsabb is, lassabb is a lejátszás, erre való a buffer, de átlagosan pontosan azonos sebességűnek kell lennie a felvételnek és a lejátszásnak. Ezt vagy kényszerkapcsolat, vagy szinkronizációs, szabályozott mechanizmus képes biztosítani, hacsak nincs valamink, ami végtelenül pontos, vagy legalább is annyira, hogy a berendezés üzemideje alatt nem ürül ki, vagy szalad túl a buffer.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Állandó, csak a felvételnél és a lejátszásnál különböző. Bár, az állandóság sem igaz. Miért lenne az? A kvarc driftje?

Vagy írd le elejétől végééig a folyamatot, a blokkvázlatát, s igazold, hogy a Te eseted egészen más - hiszen valóban lehet, hogy félreértem a problémát -, vagy mutass rá, a fenti leírásom hol nem stimmel szerinted.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Mit állítasz? Nem érted, amit írok, vagy érted ugyan, de azt mondod, másképp működik? Én pusztán arról írtam, hogy lehetséges a működésből fakadóan buffer underrun úgy, hogy jók a driver-ek, és CPU futásidő is van bőven.

Egyébként csak fel szerettem volna hívni a figyelmed erre a lehetőségre. Ettől még szíved joga, hogy hülyének nézz, pláne azok után, hogy egy számpéldán keresztül is igyekeztem ezt megvilágítani. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"pár Buffer overrun!-bejegyzést biggyeszt a logba."
vs
"lehetséges a működésből fakadóan buffer underrun"

FAIL.

"lehetséges a működésből fakadóan"

Most erted vagy nem erted a mukodeset? Mert az, amit itt eloadtal, az meg nekem is halyogkovacsolasnak tunik, pedig ha valaki, hat en nem ertek a hangtechnikahoz. A fene ott enne meg az egeszet, ha ugy mukodne, ahogy te itt elmondtad.

Amennyire _en_ latom, vannak standardok, amikhez azert legalabbis probalnak a szoftverek igazodni, es nem igazan lattam meg olyan szoftvert, ami bar azt allitotta magarol, hogy o 44100-zal vesz, valojaban bizonyithatoan ennel lenyegesen kevesebbel vett volna.

Arrol nem is beszelve, hogy a mintaveteli frekvenciaban mutatkozo kulonbseg ott lehetne _esetleg_ relevans, ha az analog hang 1:1 menne at a halozaton. Mivel azonban a hangkartya eleve egy analog-digitalis konverter, vagyis abbol a szamitogep oldalan csak digitalis hangot szedsz ki (a legtobb felvevo raadasul eleve be is tomoriti MP3-ba vagy ilyesmibe), eselytelen vagy elbukni a mintaveteli frekvencian, hiszen az onnantol kezdve nem szamit, az szamit, hogy hany bit megy at a halozaton masodpercenkent, mert ez lesz a legszukebb keresztmetszete a rendszernek. A mai processzorok annyira gyorsan tomoritenek ki es be zeneket, hogy a hangkartyak eselytelenek olyan gyorsan lejatszani a zenet, amit eloallitanak. Nem a 3 MHZ-s Sinclair ZX Spectrumok korat eljuk, hogy a hangkartyanak lejatszas kozben eselye legyen buffer underrunt generalni (nem mintha ez lenne a baj).
De ez az egesz egy ruhes aszinkron lejatszas, mert a streaming az manapsag mar joreszt aszinkron, a szerver is bufferel egy csomot, hogy legyen mibol a klienseknek feltolteni a bufferet.

Ami itt igazabol _talan_ gond lehet, az az, hogy a feltoltesi savszelesseg idonkent valtozik, es ez befolyasolja a feltoltes utemet.
--
Blog | @hron84
Üzemeltető macik

Látom, „megértetted”, amit írtam.

1. Amit fejtegettem, nem okoz problémát, ha konzerv anyagot stream-elünk. Tehát előre felvett mp3 stream esetében ez az egész kérdés nem létezik.

2. Az általam felvetett probléma egyedül akkor létezik, ha élő hangot kell átvinni, azaz a felvétel készítése, annak digitalizálása, hálózaton történő továbbítása, lejátszása egyidőben történik. Gondodld végig, miért gyökeresen más ez a konzerv anyag lejátszásához képest.

Amennyiben a konzerv anyagot a névleges mintavételi frekvenciától minimálisan eltérő mintavételezéssel hallgatjuk vissza, úgy vagy picit gyorsabban, vagy picit lassabban kerül lejátszásra a felvétel. És? Senki nem veszi észre, a bufferek töltése igény szerint file-ból történik.

Élő hangnál az a gond, hogy kis mértékben eltérő mennyiségű hanganyag keletkezik, mint kerül elfogyasztásra adott idő alatt. Ebből fakadóan csak idő kérdése, mikor fogy el a buffer tartalma, vagy az ugyan lassan, de mindig csak hízik. Ez ellen, ahogy írtam, lehet védekezni, mégpedig időbélyegek küldésével és resamping megoldással, azaz szabályozással.

Ami a szabványokat illeti, az remek, de attól, hogy 44100 Hz a mintavételi frekvencia nominális értéke, még nem lesz egy atomóra a PC-dben annak érdekében, hogy ez a frekvencia pontosan ennyi is legyen. Kis eltérés esetén viszont már létezik a probléma.

Az igazsághoz hozzátartozik, hogy kis frekvencia eltérés esetén igen sok idő kell a buffer alulcsordulásához, de folyamatosan stream-elt élő hangnál órák vagy napok alatt várhatóan össze fog jönni. Másik irányban pedig vagy a túlcsordulás, vagy a buffer hízása, egyfajta memory leak. Ez utóbbi a jobbik eset, mert napok alatt is csak elenyésző mennyiségű memóriát kellene még allokálni.

Gondold végig, de ha nincs kedved, az sem baj.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"felvétel készítése, annak digitalizálása, hálózaton történő továbbítása, lejátszása egyidőben történik."

De hat nem egy idoben tortenik, pont ez a lenyege a modern streaming technologiaknak. Az, amit te a streamben hallasz, az csak korulbelul jatszodik valos idoben, valojaban a kliensek kb. 6-10 masodperccel (videonal 10-20 masodperccel) korabbi anyagot hallanak, mert a szerver legalabb ennyit pufferel, hogy legyen mivel a menet kozben beeso kliensek pufferet feltolteni.

Amit a puffer alul/tulcsordulasarol irsz, az akkor lenne igaz, ha mindenki kieroszakolna a _tenyleges_ valos idoben valo lejatszast. Ez azonban pl. egy webradional baromira nem feltetel. Ez nem a klasszikus "lenemitom a tevet, es kihangositom a Vitrayt/Knezyt/Palikot a radioban" esete, ahol az analog jeltovabbitas miatt kvazi minimalis elcsuszas van. Hallgass meg barmilyen elo streamet ugy, hogy kozben latod a beszelot eloben, egybol ra fogsz jonni, hogy itt senki sem torekszik a valos idoben torteno hangtovabbitasra. Minden egyes reteg jonehany masodpercnyi pufferrel rendelkezik, vagyis ez igazabol mar majdnem olyan, mintha konzervet streamelnenk.
--
Blog | @hron84
Üzemeltető macik

Elfogadom az érvelésed, amennyiben mondandód lényege az volt, hogy olyan sok hangminta van a bufferben, hogy a stream élete alatt a felvételi és lejátszási mintavételi frekvenciák különbsége miatt a buffer nem tud kiürülni. Legfeljebb fogy, de a streamelésnek hamarabb vége lesz, mint elfogyjon a buffer tartalma. (Ugye a buffer a két sebesség különbségéből származó tempóban hízik, vagy fogy.)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Igen, valoszinuleg a streamer nem tudja olyan utemben feltotleni a szerverre a streamet, mint kellene, es tulcsordul a bejovo buffere. Korbe kellene nezni a halozatban, hogy nincs-e valami, ami idonkent feltolteseket intez (pl. egy elrontott idozitesu backup), ezzel lefogva a feltoltesi savszelt.
--
Blog | @hron84
Üzemeltető macik