[Mplayer-cvslog] CVS: main/DOCS/Spanish tech,NONE,1.1
TeLeNiEkO
telenieko at users.sourceforge.net
Sun Mar 18 20:28:15 CET 2001
Update of /cvsroot/mplayer/main/DOCS/Spanish
In directory usw-pr-cvs1:/tmp/cvs-serv14668
Added Files:
tech
Log Message:
Translated the technical documentation
--- NEW FILE ---
Bien, voy a describir como funciona todo esto.
Las bases de la estructura del programa son, basicamente, lojicas. De todos
modos es un gran puzzle
Los modulos principales:
1. streamer.c: Es la entrada, lee el archivo o el VCD. Necesita conocer:
buffereado apropiado, busquedas, funciones de salto, lectura por
bytes o bloques de cualquier tamaño,,
La esctructura stream_t describe el stream de entrada, archivo/
dispositivo
2. demuxer.c: Esto se ocupa del demultiplezado de la entrada en audio y video
y su lectura por paquetes bufereados.
demuxer.c es basicamente un esqueleto comun a todos los formatos de
entrada, equipado con algunos parsers para cada uno (mpeg-es,
mpeg-ps, avi, avi-ni, asf), estos estan en los archivos demux_*.c.
La estructura es la demuxer_t. Solo hay una.
2.a. demuxer stream, DS. La estructura es demux_stream_t
Cada canal (a/v) tiene uno,
Por ahora hay 2 por demuxer, uno para audio y otro para video.
2.b. demux_packet_t, DP.
Este contiene un fragmento (avi) o paquete (asf,mpg).
En la memoria se almacenan como una lista encadenada, ya que son
de tamaños diferentes.
Ahora, como funciona esta lectura?
- demuxer.c/demux_read_data() es llamado, toma 'cuantos bytes' y donde
(de la memoria), queremos leer, y de que DS. Lo llaman los codecs.
- este cromprueva si el buffer del DS contiene algo, entonces lee los
bytes que sea necesario. Si no hay suficientes llama a fill_byes() que:
- Comprueva si el DS tiene paquetes buffereados (DP), entonces mueve
los mas viejos al buffer, y sigue leyendo. Si la lista esta vacia
llama a demux_fill_buffer():
- Esta llama al procesador del formato de entrada, que lee el
fichero adelante, y mueve los paquetes encontrados a sus buffers
respectivos.
Bien, quisieramos un packete de audio pero solo algunos fragmentos de video
estan disponibles, entonces tarde o temprano el error:
DEMUXER: Too many (%d in %d bytes) audio packets in the buffer
se mostraria.
Asi pues, por ahora esta todo bien. Tenemos intencion de moverlo a una lib
separada.
Sigamos:
3. mplayer.c - ohh, el rey de la fiesta :)
La correcion de tiempo esta aqui ya que se ha de/recomienda tratar de forma
diferente por cada formato, y a veces se puede hacer de muchas maneras. Estan
las variables float a_frame y v_frame, que contienen la posicion a/v mas
reciente en segundos. Una nueva imagen es mostrada si v_frame<a_frame, y el
sonido se descodifica si a_frame<v_frame.
Durante la reproduccion (a/v), se aumentan las variables por la duracion de
la reproduccion a/v. En video, es habitual 1.0fps, pero cabe menvionar que
esto no afecta al video. Por ejemplo ASF no tiene esta caracteristica, en su
lugar esta "duration" y puede cambiar por imagenes. MPEG2 tiene "repeat_count"
que retrasa la imagen pos 1-2.5... Quizas solo AVI y MPEG1 tienen el fps correcto
Asi pues todo funciona a la perfeccion mientras el audio y el video estan en una
perfecta sincronia, mientras el audio avanza da tiempos, y si el tiempo para una
imagen se supera se muestra la siguiente. Pero, ¿que pasa si no estan sincronizados
en el archivo de origen? Entonces la correcion PTS entra en escena. Los demuxers
de entrada leen el PTS (Marca de tiempo de presentacion [Presentation TimeStamp])
de los paquetes, y con esto podemos ver si los canales estan sincronizados. Entonces
MPlayer puede corregir a_frame con un limite (mira la opcion -mc). Un sumario de las
correciones puede encontrarse en c_total.
Obviamente esto no es todo, hay muchas cosas conflictivas. Por ejemplo las tarjetas
de sonido se retrasan, por eso MPlayer necesita conocer el tamaño del buffer de audio
Este puede medirse con select(), que, lamentablemente, no esta soportado por todas
las tarjetas... por eso existe la opcion -abs.
Hay otro problema, MPEG, el PTS no se da por imagenes si no por sectores, que
pueden contener 10 imagenes, o 0.1. Por tanto, para que esto no se cargue nuestro
control de tiempo establecemos una media de 5 imagenes en el PTS y arreglado.
Las cosas no se simplificaron con AVI. Hay el metodo decontrol de tiempo "oficial",
el basado en BPS, de modo que la cabecera contiene cuantos bytes de audio
comprimido pertenecen a cada segundo de imagenes. Obviamente esto no funciona siempre
Asi pues, emulamos el metodo PTS/sector del MPEG en los AVI. Asi el procesador de AVI
calcula un PTS 'falso' calculado segun el tipo de imagenes.
En los AVI, normalmente hay una parte de audio mayor almacenada al principio, y
sigue el video. Esto debe ser medido en el retraso, se llama "Retraso PTS inicial"
Obviamente hay dos, uno en la cabecera (y raramente usado) y el otro que no esta
en ningun lugar, asi que unicamente puede medirse.
4. Codecs. Son librerias separadas...
Por ejemplo libac3, libmpeg2, xa/*, alaw.c, opendivx/*, loader, mp3lib.
mplayer.c los llama cuando una porcion de audio/video necesita ser reproducida
(mira el principio del punto 3), y llama al demuxer apropiado para descomprimir
los datos (mira el punto 2).
5.a Controlador del codec: el 'puzzle' msa grande del monton
La libmpeg2 es tan inestable que no puedo creerlo. Obviamente no digo que sea
un asco :) Mas bien, no acepta steams perfectos. Si hay algun error simplemente
da una violacion de segmento ;) Y no empieces a reir, es bueno de este modo
desde el punto de vista de la velocidad seria un 50-100% mas lento si estuviera
lleno de verificaciones. Es por esto que lo solucionamos ejecutandolo en un
proceso separado, y si muere, quien se preocupa?, simplemente inicia otro.
De todos modos, algunas cosas son necesarias para esto:
- El proceso de control del codec: un proceso separado, que duerme, pero si
el hijo muere (el proceso de libmpeg2), rapidamente inicia otro. Asi MPlayer
no debe preocuparse al respecto, simplemente vuelca los datos comprimidos
al hijo, que los muesta.
- shmem: Los datos comprimidos, y las imagenes descomprimidas se encuentran
en memoria compartida, asi pues los 3 procesos (mplayer, codecontrol,
codec libmpeg2) los ve, de modo que pueden pasarse datos mas deprisa.
- FIFO se usa para la comunacion entre los procesos
- Si el hijo muere durante la decodificacion, los datos decodificados no se
pierden, son heredados por el nuevo hijo via la memoria compartida! Asi
pues, unicamente, un pequeño error puede verse en el video. No desaparecera
o se volvera verde, como en las viejas versiones
El contrapunto de todo esto es que desde que libvo y libmpeg2 estan estrechamente
relacionados libvo necesita trabajar en el mismo proceso que libmpeg2, en el que
se ocupa de morir/renacer, y no en el que lleva el control, MPlayer. Esto causa
un monton de problemas, la mayoria en el manejo de la ventana de libvo (tecleo,
etc...). Asi que hay algunos truquitos varios por en medio, mucho FIFO, y trucos
que se aprovechan del hecho de que las X no se preocupan sobre que proceso
controla los eventos.
Quisiera resolver esto en un futuro, y usar el metodo signal/longjump, otro
puzlecito, desarroyado en la lista mpeg2dec-devel.
5. libvo: Este muestra la imagen, hay dos rutinas para ello
5.a draw_slice():
Esto muestra dibujos YV12 (3 imagenes, a maximo tamaño que contienen,
brillos, y dos a un cuarto de tamaño que contienen la informacion de color).
Los codecs MPEG (libmpeg2, opendivx) usan esta rutina. Esta no necesita mostar
la imagen completa, unicamente actualizar algunas partes de esta.
5.b draw_frame():
Esta es la interficie antigua, unicamente muestra imagenes completas, y,
unicamente, puede tratar formatos empaquetados (YUY2, RGB/BGR). Esta rutina
la usan los codecs Win32 (DivX, Indeo, etc...)
_______________________________________________
Mplayer-cvslog mailing list
Mplayer-cvslog at lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/mplayer-cvslog
More information about the MPlayer-cvslog
mailing list