86
|
1 [yes, this is hungarian. maybe someone will translate this to russian or
|
|
2 something else...]
|
|
3
|
|
4 Nos, akkor leirom, hogyan is működik ez az egész.
|
|
5
|
|
6 Az ékezetekkel majd lesz valami, nem nagyon vagyok hozzászokva az
|
|
7 ékezetes gépeléshez...
|
|
8
|
|
9 A program felépítése alapjaiban logikus, de eleg gányul van megirva :)
|
|
10
|
|
11 A fő modulok:
|
|
12
|
|
13 1. streamer.c: ez az input, azaz ez olvassa a filet vagy VCD-t.
|
|
14 amit tudnia kell: megfelelő bufferelés, seek, skip funkciók,
|
|
15 byte-onkénti ill. tetszőleges méretű blockonkénti olvasás.
|
|
16 Egy stream (input device/file) leírására a stream_t struktura szolgál.
|
|
17
|
|
18 2. demuxer.c: ez végzi az input szétszedését audio és video csatornákra,
|
131
|
19 és a kiválasztott csatornák bufferelt package-nkénti olvasását.
|
86
|
20 A demuxer.c inkább csak egy framework, ami közös minden input
|
|
21 formátumra, és az egyes formátumokhoz (mpeg-es,mpeg-ps, avi, avi-ni, asf)
|
|
22 külön parser van, ezek a demux_*.c fileokban vannak.
|
|
23 A hozza tartozo struktura a demuxer_t. osszesen egy demuxer van.
|
|
24
|
|
25 2.a. demuxer stream, azaz ds. struct: demux_stream_t
|
|
26 minden egyes csatornahoz (a/v) tartozik egy ilyen.
|
|
27 egyelore demuxer-enkent 2 ilyen lehet, egy a hanghoz es egy a kephez.
|
|
28
|
|
29 2.b. demux_packet_t, azaz dp.
|
|
30 ez egy darab chunk-ot (avi) vagy packet-et (asf,mpg) tartalmaz.
|
|
31 memoriaban ezek lancolt listaban vannak, mivel kulonbozo meretuek.
|
|
32
|
|
33 hogy is muxik ez a beolvasosdi?
|
|
34 - meghivodik a demuxer.c/demux_read_data(), megkapja melyik ds-bol
|
|
35 (audio vagy video), mennyi byteot es hova (memoriacim) szeretnenk
|
|
36 beolvasni. ezt hivogatjak gyakorlatilag a codec-ek.
|
|
37 - ez megenzi,hogy az adott ds bufferében van-e valami, ha igen akkor
|
|
38 onnan olvas amennyit kell. ha nincs/nincs eleg, akkor meghivja
|
|
39 a ds_fill_buffer()-t ami:
|
|
40 - megnezi hogy az adott ds-ben vannak-e bufferelve csomagok (dp-k)
|
|
41 ha igen, akkor a legregebbit atrakja a bufferbe es olvas tovabb.
|
|
42 ha ures a lancolt lista, akkor meghivja a demux_fill_buffer()-t:
|
|
43 - ez az input formatumnak megfelelo parset meghivja ami olvassa
|
|
44 tovabb a filet, es a talalt csomagokat rakja be a megfelelo bufferbe.
|
|
45 na ha mondjuk audio csomagot szeretennk, de csak egy rakat video csomag
|
|
46 van, akkor jon elobb-utobb a DEMUXER: Too many (%d in %d bytes) audio
|
|
47 packets in the buffer... hibauzenet.
|
|
48
|
|
49 Eddig kb tiszta ugy, ezt akarom majd atrakni kulon lib-be.
|
|
50
|
|
51 na nezzuk tovabb:
|
|
52
|
|
53 3. mplayer.c - igen, o a fonok :)
|
|
54 az idozites eleg erdekesen van megoldva, foleg azert mert minden
|
|
55 fileformatumnal maskepp kell/celszeru, es neha tobbfele keppen is lehet.
|
|
56 van egy a_frame es egy v_frame nevu float valtozo, ez tarolja az epp
|
|
57 lathato/hallhato a/v poziciojat masodpercben.
|
|
58 akkor jelenit meg ujabb video frame-t, ha v_frame<a_frame, es akkor
|
|
59 dekodol tovabb hangot ha a_frame<v_frame.
|
|
60 amikor lejatszik (hang/kep) akkor a lejatszott valami idotartamaval
|
|
61 noveli a megfelelo valtozot. videonal ez altalaban 1.0/fps, persze
|
|
62 meg kell jegyeznem hogy videonal nem igazna szamit az fps, asf-nel
|
|
63 pl. nincs is olyan, ahelyett duration van es framenkent valtozhat.
|
|
64 mpeg2-nel pedig repeat_count van ami 1-2.5 idotartamban elnyujtja
|
|
65 a framet... avi-nal van talan egyedul fix fps, meg mpeg1-nel.
|
|
66
|
|
67 Na most ez addig nagyon szepen mukodik, amig a hang es kep tokeletes
|
|
68 szinkronban van, mivel igy vegulis a hang szol, az adja az idozitest,
|
|
69 es amikor eltelt egy framenyi ido akkor kirakja a kovetkezo framet.
|
|
70 de mi van ha valamiert az input fileban csuszik a ketto?
|
|
71 Akkor jon be a PTS correction. az input demuxer-ek olvassak a csomagokkal
|
|
72 egyutt a hozzajuk tartozo PTS-t (presentation timestamp) is, ami alapjan
|
|
73 eszreveheto ha el van csuszva a ketto. ilyenkor egy megadott maximalis
|
87
|
74 hataron (lasd -mc opcio) belul kepes az mplayer korrigalni az a_frame
|
86
|
75 erteket. a korrekciok osszege van a c_total-ban.
|
|
76
|
|
77 persze ez meg nem minden szinkron ugyben, van meg nemi gaz.
|
|
78 pl. az hogy a hangkartya eleg rendesen kesleltet, ezt az mplayernek
|
87
|
79 korrigalnia kell: ezert kell neki az audio buffer merete. amit a
|
|
80 select()-e tud lemerni amit viszont nem tud minden kartya...
|
86
|
81 ilyenkor kell a -abs opcioval megadni.
|
|
82
|
|
83 aztan van olyan gond is, hogy pl. mpegnel nem framenkent van PTS
|
|
84 hanem szektoronkent, ami tartalmazhat 10 framet is de 0.1-et is.
|
87
|
85 hogy ez ne csessze el az idozitest, atlagoljuk 5 framenkent a
|
86
|
86 PTS-t es ezt az atlag erteket vesszuk figyelembe korrekcional.
|
|
87
|
|
88 avi-nal sem egyszeru az elet. ott a 'hivatalos' idozitesi mod a
|
87
|
89 BPS-alapu, azaz a headerben le van tarolva hany tomoritett audio
|
86
|
90 byte tartozik egy masodpercnyi (fps darab) kephez.
|
|
91 ez persze nem mindig mukodik... miert is mukodne :)
|
87
|
92 ezert en megcsinaltam hogy az mpeg-nel hasznalatos sectoronkenti
|
86
|
93 PTS erteket emulalom avi-ra is, azaz az AVI parser minden beolvasott
|
|
94 chunk-nal szamol egy kamu PTS-t a framek tipusa alapjan. es ez
|
|
95 alapjan idozitek. es van amikor ez mukodik jobban.
|
|
96 persze itt meg bejatszik az is, hogy AVI-nal altalaban elore letarolnak
|
|
97 egy nagyobb adag hangot, es csak utana kezdodik a kep. ezt persze
|
|
98 bele kell szamolni a kesleltetesbe, ez az Initial PTS delay.
|
|
99 ilyen persze 2 is van, az egyik a headerben le is van irva, es
|
|
100 nem nagyon hasznlajak :) a masik sehol nincs leirva de hasznaljak, ezt
|
|
101 csak merni lehet...
|
|
102
|
|
103 4. codecek. ezek kulonbozo lib-ek szanaszet mindenfelol.
|
|
104 mint pl. libac3, libmpeg2, xa/*, alaw.c, opendivx/*, loader, mp3lib.
|
|
105 az mplayer.c hivogatja oket amikor egy egy darab hangot vagy framet
|
|
106 kell lejatszani (lasd 3. pont elejen)
|
|
107 ezek pedig hivjak a megfelelo demuxert hogy megkapjak a tomoritett
|
|
108 adatokat (lasd 2. pont).
|
|
109
|
|
110 5. libvo: ez vegzi a kep kirakasat. jelenleg 2 kulonbozo kepkirako
|
|
111 van benne:
|
|
112 5.a draw_slice(): ez planar YV12 kepet rak ki (3 db frame, egy teljes
|
|
113 meretu ami a fenyerot tartalmazza, es 2 negyedakkora, ami a
|
|
114 szin infot). ezt hasznaljak az mpeg codecek (libmpeg2,opendivx).
|
|
115 ez mar tud olyat hogy nem az egesz kep kirakasa, hanem csak kis
|
|
116 reszletek updatelese: ilyenkor a sarkanak es a darabka meretenek
|
|
117 megadasaval lehet csinalni.
|
|
118 5.b draw_frame(): ez a regebbi interface, ez csak komplett framet rak ki,
|
|
119 es csak packed formatumot (YUY2, RGB/BGR) tud.
|
|
120 ezt hasznaljak a win32 codecek (divx,indeo stb).
|
|
121
|