Nos, akkor lerom, hogyan is mkdik ez az egsz.

A f modulok:

1. streamer.c: ez az input layer, azaz ez olvassa a filet, VCD-t vagy stdin-t.
   amit tudnia kell: megfelel sectoronknti bufferels, seek, skip funkcik,
	 byte-onknti ill. tetszleges mret blockonknti olvass.
	 Egy stream (input device/file) lersra a stream_t struktra szolgl.

2. demuxer.c: ez vgzi az input sztszedst audio s video csatornkra,
   s a kivlasztott csatornk bufferelt package-enknti olvasst.
	 A demuxer.c inkbb csak egy framework, ami kzs minden input
	 formtumra, s az egyes formtumokhoz (mpeg-es, mpeg-ps, avi, avi-ni,
	 asf) kln parser van, ezek a demux_*.c file-okban vannak.
	 A hozz tartoz struktra a demuxer_t. sszesen egy demuxer van.

2.a. demux_packet_t, azaz dp.
   ez egy darab chunk-ot (avi) vagy packet-et (asf, mpg) tartalmaz.
	 memriban ezek lncolt listban vannak, mivel klnbz mretek.

2.b. demuxer stream, azaz ds.
   struct: demux_stream_t
   minden egyes csatornhoz (a/v) tartozik egy ilyen.
	 ez tartalmazza a stream-hez tartoz packeteket (lsd. 2.a.)
	 egyelre demuxer-enknt 3 ilyen lehet:
	 - hang (d_audio)
	 - kp  (d_video)
	 - DVD felirat (d_dvdsub)

2.c. stream header. 2 fle van (egyelre): sh_audio_t s sh_video_t
   ez tartalmaz minden, a dekdolshoz szksges paramtert, gy az input
   s output buffereket, kivlasztott codecet, fps/framerate stb adatokat.
   Annyi van belle, ahny stream van a file-ban trolva. Lesz minimum egy
   a videohoz, ha van hang akkor ahhoz is, de ha tbb audio/video stream
   is van, akkor mindegyikhez lesz egy ilyen struct.
   Ezeket avi/asf esetn a header alapjn tlti fel a header beolvas,
   mpeg esetn pedig a demux_mpg.c fogja ltrehozni, ha egy j streamet
   tall. j stream esetn ====> Found audio/video stream: <id>  jelenik meg.

   A kivlasztott stream header s a hozz tartoz demuxer stream klcsnsen
   hivatkoznak egymsra (ds->sh s sh->ds) az egyszerbb hasznlat vgett.
   (gy a funkcitl fggen elg vagy csak a ds vagy csak az sh tadsa)

   Plda: van egy .asf file-unk, abban 6 db stream, ebbl 1 audio s 5 video.
   A header beolvassakor ltre fog jnni 6 db sh struct, 1 audio s 5 video.
   Amikor elkezdi olvasni a packeteket, az els tallt audio s video
   packethez tartoz streamet kivalasztja, es ezekre allitja be a d_audio
   s d_video sh pointereit.
   gy a ksbbiekben mr csak ezeket a streameket olvassa, a tbbit nem.
   Persze, ha a user msik streameket szeretne kivlasztani, akkor
   force-olhatja az -aid s -vid kapcsolkkal.
   J pelda erre a DVD, ahol nem mindig az angol szinkron hang az els
   megtallt stream, s gy random minden vob ms nyelven szlalhat meg :)
   Ilyenkor kell pl. az -aid 128 kapcsolt hasznlni.

  hogy is mxik ez a beolvassdi?
	 - meghvdik a demuxer.c/demux_read_data(), megkapja melyik ds-bl
	   (audio vagy video), mennyi byte-ot s hova (memriacm) szeretnnk
		 beolvasni. Ezt hvogatjk gyakorlatilag a codec-ek.
	 - ez megnzi, hogy az adott ds bufferben van-e valami, ha igen akkor
	   onnan olvas, amennyit kell. Ha nincs/nincs elg, akkor meghvja
		 a ds_fill_buffer()-t ami:
	 - megnzi, hogy az adott ds-ben vannak-e bufferelve csomagok (dp-k)
	   ha igen, akkor a legrgebbit trakja a bufferbe s olvas tovbb. Ha
		 res a lncolt lista, akkor meghvja a demux_fill_buffer()-t:
	 - ez az input formtumnak megfelel parser-t hvja meg, ami tovbbol-
	   vassa a file-t, s a tallt csomagokat berakja a megfelel bufferbe.
		 Na, ha mondjuk audio csomagot szeretnnk, de csak egy rakat
		 video csomag van, akkor jn elbb-utbb a DEMUXER: Too many
		 (%d in %d bytes) audio packets in the buffer... hibazenet.

Eddig kb. tiszta gy, ezt akarom majd trakni kln lib-be.

na nzzuk tovbb:

3. mplayer.c - igen,  a fnk :)

    F feladata a klnbz modulok sszekapcsolsa, illetve az A-V
    szinkron biztostsa.

    Az adott stream aktulis pozcija a megfelelo stream header
    (sh_audio / sh_video) timer field-ben van.
    (Rgen ez volt az a_frame s egy v_frame nev float vltoz)

	 A lejtsz ciklus felptse:
	 while(not EOF) {
	     fill audio buffer (read & decode audio) + increase a_frame
	     read & decode a single video frame + increase v_frame
	     sleep  (wait until a_frame>=v_frame)
	     display the frame
	     apply A-V PTS correction to a_frame
	     check for keys -> pause,seek,...
	 }

	 amikor lejtszik (hang/kp) akkor a lejtszott valami idtartamval
	 nveli a megfelel vltozt:
	 - audionl ez a lejtszott byte-ok / sh_audio->o_bps
	 megj.: i_bps = tmrtett byte-ok szma egy msodpercnyi hanghoz
	        o_bps = tmrtetlen byte-ok szma egy msodpercnyi hanghoz
	            (ez utbbi == bps*samplerate*channels)
	 - videonl ez ltalban az sh_video->frametime.
	 Ez ltalban == 1.0/fps, persze meg kell jegyeznem, hogy videonl nem
	 igazn szmt az fps, asf-nl pl. nincs is olyan, ahelyett duration
	 van s frame-enknt vltozhat.
	 mpeg2-nl pedig repeat_count van, ami 1-2.5 idtartamban elnyjtja
	 a frame-et... avi-nl van taln egyedl fix fps, meg mpeg1-nl.

	 Na most ez addig nagyon szpen mkdik, amg a hang s kp tkletes
	 szinkronban van, mivel gy vglis a hang szl, az adja az idztst,
	 s amikor eltelt egy frame-nyi id, akkor kirakja a kvetkez frame-et.
	 De mi van, ha valamirt az input file-ban csszik a kett?
	 Akkor jn be a PTS correction. Az input demuxer-ek olvassk a
	 csomagokkal egytt a hozzjuk tartoz PTS-t (presentation timestamp)
	 is, ami alapjn szrevehet, ha el van csszva a kett. Ilyenkor egy
	 megadott maximlis hatron (lsd -mc opci) bell kpes az mplayer
	 korrigalni az a_frame rtkt. A korrekcik sszege van a c_total-ban.

	 Persze ez mg nem minden szinkron gyben, van mg nmi gz. Pl. az,
	 hogy a hangkrtya elg rendesen ksleltet, ezt az mplayernek korriglnia
	 kell! Az sszes audio ksleltets msodpercben ezek sszege:
	 - az utols timestamp (PTS) ta beolvasott byte-ok:
	   t1 = d_audio->pts_bytes/sh_audio->i_bps
	 - Win32/ACM esetn az audio input bufferben trolt byte-ok:
	   t2 = a_in_buffer_len/sh_audio->i_bps
	 - az audio out bufferben trolt tmrtetlen byte-ok:
	   t3 = a_buffer_len/sh_audio->o_bps
	 - a hangkrtya bufferben (vagy DMA bufferben) trolt, mg nem
	   lejtszott byte-ok:
	   t4 = get_audio_delay()/sh_audio->o_bps

	 Ezekbl kiszmolhat egszen pontosan, hogy az pp hallhat hanghoz
	 milyen PTS tartozik, majd ezt sszevetve a video-hoz tartozo PTS-el
	 meg is kapjuk az A-V eltrst!

	 Avi-nl sem egyszer az let. Ott a 'hivatalos' idztsi md a
	 BPS-alap, azaz a headerben le van trolva, hny tmrtett audio
	 byte vagy chunk tartozik egy msodpercnyi (fps darab) kphez.
	 Az AVI stream headerben van 2 fontos mezo, a dwSampleSize, es
	 a dwRate/dwScale arnypr:
	 - Ha a dwSampleSize 0, akkor VBR stream, tehat nem konstans a
	 bitrate. Ilyenkor 1 chunk tarol 1 sample-t, es a masodpercenkenti
	 chunkok szamat adja a dwRate/dwScale.
	 - Ha a dwSampleSize>0, akkor constant bitrate van, es az ido igy
	 szamolhato:  time = (bytepos/dwSampleSize) / (dwRate/dwScale)
	 (tehat a sample sorszamat elosztjuk a samplerate-el)
	 Ilyenkor stream-kent kezelheto az audio, ami tetszolegesen
	 chunk-okra van darabolva, de lehet akar 1 db chunk is az egesz.
	 
	 A msik lehetsg csak az interleaved fileoknl hasznlhat: a
	 chunk-ok sorrendjbl szmolhat egy timestamp (PTS) rtk.
	 A video chunkok PTS-e egyszer: chunk szma * fps
	 Az audio pedig az eltte lev video chunk-val azonos.
	 Ilyenkor viszont szamolni kell az ugynev. "audio preload"-al is,
	 azaz van egy fix kesleltetes az audio es video stream-ek kozott.
	 Ez altalaban 0.5-1.0 sec, de van amikor egeszen mas.
	 A pontos erteket regen mertuk, most a demux_avi.c kezeli le:
	 az elso video utani audio chunknal kiszamolja az A-V elterest,
	 es ezt veszi az audio preload mertekenek.
	 
3.a. audio playback:
	 pr sz az audio lejtszsrl:
	 az egszben nem maga a lejtszs a nehz, hanem:
	 1. hogy tudjuk, mikor lehet rni a bufferbe, blocking nlkl
	 2. hogy tudjuk, mennyit jtszott mr le abbl, amit a bufferbe rtunk
	 Az 1. az audio dekdolshoz kell, valamint hogy a buffert mindig teli
	 llapotban tudjuk tartani (gy sose fog megakadni a hang).
	 A 2. pedig a korrekt idztshez szksges, ugyanis nmely hangkrtya
	 akr 3-7 msodpercet is ksleltet, ami azrt nem elhanyagolhat!
	 Ezek megvalstsra az OSS tbbfle lehetsget is knl:
	 - ioctl(SNDCTL_DSP_GETODELAY): megmondja, hny lejtszatlan byte
	   vrakozik a hangkrtya bufferben -> idztshez kivl,
	   de nem minden driver tmogatja :(
	 - ioctl(SNDCTL_DSP_GETOSPACE): megmondja, mennyit rhatunk a krtya
	   bufferbe blocking nlkl. Ha a driver nem tudja a GETODELAY-t,
	   akkor ezt hasznalhatjuk arra is, hogy megtudjuk a ksleltetst.
	 - select(): meg kne mondja, hogy rhatunk-e a krtya bufferbe
	   blocking nlkl. Azt, hogy mennyit rhatunk, nem mondja meg :(
	   valamint sok driverrel egyltaln nem, vagy rosszul mkdik :((
	   csak akkor hasznlom, ha egyik fenti ioctl() sem mkdik.

4. codecek. ezek klnbz lib-ek szanaszt mindenfell.
   mint pl. libac3, libmpeg2, xa/*, alaw.c, opendivx/*, loader, mp3lib.
   
   Az mplayer.c nem kozvetlenul hivja oket, hanem a dec_audio.c es a
   dec_video.c fileokon keresztul, igy az mplayer.c-nek nem kell semmit
   sem tudnia a codecrol. 
   
5. libvo: ez vgzi a kp kirakst.

  Az img_format.h-ban definilva vannak konstansok a klnbz pixel-
  formtumokhoz, ezeket ktelez hasznlni.

  1-1 vo drivernek a kvetkezket kell ktelezen implementlnia:

  query_format()  - lekrdezi, hogy egy adott pixelformat tmogatott-e.
                    return value:  flags:
		       0x1 - supported (by hardware or with conversion)
		       0x2 - supported (by hardware, without conversion)
		       0x4 - sub/osd supported (has draw_alpha)
  FONTOS: minden vo drivernek ktelez tmogatnia az YV12 formtumot, s
  egyiket (vagy mindkettt) a BGR15 s BGR24 kzl, ha kell, konvertlssal.
  Ha ezeket nem tmogatja, akkor nem fog minden codec-kel mkdni!
  Ennek az az oka, hogy az mpeg codecek csak YV12-t tudnak ellltani,
  a rgebbi Win32 DLL codecek pedig csak 15 s 24bpp-t tudnak.
  Van egy gyors MMX-es 15->16bpp konvertl, gy az nem okoz klnsebb
  sebessgcskkenst!

  A BPP tblzat, ha a driver nem tud bpp-t vltani:
      jelenlegi bpp:    ezeket kell elfogadni:
           15                    15
	   16                    15,16
	   24                    24
	   24,32                 24,32

  Ha tud bpp-t vltani (pl. DGA 2, fbdev, svgalib) akkor, ha lehet, be kell
  vltani a krt bpp-re. Ha azt a hardver nem tmogatja, akkor a legkzelebbi
  mdra (15 esetn 16-ra, 24 esetn 32-re) kell vltani s konvertlni!

  init() - ez hvdik meg a legels frame kiraksa eltt - bufferek foglalsa
           stb a clja.
	   van egy flags paramter is (rgen fullscreen volt a neve):
	   0x01 - fullscreen (-fs)
	   0x02 - vidmode switch (-vm)
	   0x04 - scaling enabled (-zoom)
	   0x08 - flip image (upside-down)

  draw_slice(): ez planar YV12 kpet rak ki (3 db plane, egy teljes
	 mret, ami a fnyert (Y) tartalmazza, s 2 negyedakkora, ami a
	 szn (U,V) inft). ezt hasznljk az mpeg codecek (libmpeg2, opendivx).
	 ez mr tud olyat, hogy nem az egsz kp kiraksa, hanem csak kis
	 rszletek update-else: ilyenkor a sarknak s a darabka mretnek
	 megadsval lehet hasznlni.

  draw_frame(): ez a rgebbi interface, ez csak komplett frame-et rak ki,
	 s csak packed formtumot (YUY2 stb, RGB/BGR) tud.
	 ezt hasznljk a win32 codecek (divx, indeo stb).

  draw_alpha(): ez rakja ki a subtitle-t s az OSD-t.
	 hasznlata kicsit cseles, mivel ez nem a libvo API rsze, hanem egy
	 callback jelleg cucc. a flip_page() kell meghvja a vo_draw_text()-et
	 gy, hogy paramterknt tadja a kperny mreteit s a pixel-
	 formtumnak megfelel draw_alpha() implementcit (function pointer).
	 Ezutn a vo_draw_text() vgigmegy a kirajzoland karaktereken, s
	 egyenknt meghvja minden karakterre a draw_alpha()-t.
	 Segtsg kppen az osd.c-ben meg van rva a draw_alpha mindenfle
	 pixelformtumhoz, ha lehet ezt hasznld!

  flip_page(): ez meghvdik minden frame utn, ennek kell tnylegesen meg-
	 jelenteni a buffert. double buffering esetn ez lesz a 'swapbuffers'.

6. libao2: ez vezrli a hang lejtszst

  A libvo-hoz (lsd 5.) hasonlan itt is klnbz driverek vannak, amik
  egy kzs API-t (interface) valstanak meg:

static int control(int cmd,int arg);
  Ez egy ltalnos cl fggvny, a driverfgg s egyb specilis paramterek
  olvassra/belltsra. Egyelre nem nagyon hasznlt.

static int init(int rate,int channels,int format,int flags);
  Driver initje, ilyenkor kell megnyitni a device-t, belltani samplerate,
  channels, sample format paramtereket.
  Sample format: ltalban AFMT_S16_LE vagy AFMT_U8, tovbbi defincikrt
  lsd. dec_audio.c ill. linux/soundcard.h file-okat!

static void uninit();
  Talld ki!
  Na j, segtek: lezrja a device-t, kilpskor (mg nem) hvdik meg.

static void reset();
  Reseteli a device-t. Egsz pontosan a bufferek trlsre szolgl,
  teht hogy a reset() utn mr ne szljon tovbb az, amit eltte kapott.
  (pause ill. seek esetn hvdik meg)

static int get_space();
  Vissza kell adja, hogy hny byte rhat az audio bufferbe anlkl, hogy
  blockolna (vrakoztatn a hv processt). Amennyiben a buffer (majdnem)
  tele van, 0-t kell visszaadni!
  Ha sosem ad vissza 0-t, akkor nem fog mkdni az MPlayer!

static int play(void* data,int len,int flags);
  Lejtszik egy adag hangot, amit a data cm memriaterleten kap s len
  a mrete. a flags mg nem hasznlt. Az adatokat t kell msolnia, mert a
  hvs utn fellrdhatnak! Nem kell felttlen minden byte-ot felhasznlni,
  hanem azt kell visszaadnia, mennyit hasznlt fel (msolt a bufferbe).

static int get_delay();
  Vissza kell adja, hogy hny byte vrakozik az audio bufferben. lehetleg
  minl pontosabban, mert ettl fgg az egsz idzts!
  Legrosszabb esetben adja vissza a buffer mrett!

!!! Mivel a kp a hanghoz (hangkrtyhoz) van szinkronizlva, gy nagyon fontos,
!!! hogy a get_space ill. get_delay fggvnyek korrektl legyenek megrva!

