Newsgroup: it.comp.software.divx
Titolo: [linux] utility per impostare ritardi su file AVI

Ho scritto una semplicissima utility a riga di comando (per ora
compilata solo per Linux), che permette di impostare ritardi su
qualsiasi traccia contenuta in un file AVI.
Si puo' scaricare da qui:
http://fsinapsi.altervista.org
(cliccando su "AVI-delay" nella parte a destra, oppure seguendo
il percorso a partire da "Codice" nella parte a sinistra).
E' uno zip (avi-delay.zip) di 85178 bytes, che contiene due
soli file: il codice sorgente (che ho scritto poco fa), e il
compilato eseguibile ELF, che richiede solo queste librerie:
$ ldd avi-delay       
        libgmp.so.3 => /usr/lib/libgmp.so.3 (0x40033000)
        libm.so.6 => /lib/i686/libm.so.6 (0x40060000)
        libc.so.6 => /lib/i686/libc.so.6 (0x42000000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
(Sono librerie presenti praticamente in qualsiasi installazione
di linux.)
Il programma e' piuttosto rozzo, ma anche semplicissimo da usare.
Battendo "avi-delay" senza argomenti, viene stampato questo
messaggio:
--------------------------------------------------------------------------
$ avi-delay 
Uso: avi-delay <path> [ <traccia> <ritardo> ]
  <path> č il path del file AVI
  <traccia> č un numero che indica la traccia (0=video, 1=primo audio, etc)
  <ritardo> č un numero intero che indica il ritardo in millisecondi
Specificando solo il path si ottengono informazioni sull'AVI.
--------------------------------------------------------------------------
Specificando un solo argomento (un file AVI), vengono stampate
alcune informazioni; in pratica vengono mostrati solo gli attuali
ritardi impostati su tutti gli stream.
Esempio:
$ avi-delay prova.avi 
ritardo video (traccia 0): 0 ms
ritardo audio (traccia 1): 0 ms
Il file prova.avi ha uno stream video e una sola traccia audio,
ed entrambi hanno un ritardo impostato a 0.
Per impostare un ritardo occorre specificare 3 argomenti: il
primo e' il file AVI, il secondo e' il numero dello stream
che ci interessa (il numero e' quello mostrato tra parentesi
quando si esegue il programma specificando un solo argomento;
quindi, il video sara' sempre la traccia 0, il primo audio
sara' la numero 1, il secondo audio sara' la numero 2, e
cosi' via...); il terzo argomento e' il ritardo desiderato
(sempre positivo) in millisecondi.
Ad esempio, se vogliamo ritardare il primo (e unico) audio
di 200 ms, batteremo il comando:
$ avi-delay prova.avi 1 200
hai chiesto un ritardo di 200 ms,
ma il valore usabile piů simile č di 208.979591 ms
tento di modificare il ritardo 0 -> 208.979591
tutto ok
Il programma ci informa che non puo' esaudire la richiesta
con la massima precisione, e che dobbiamo accontentarci di
un ritardo di 208.979591 ms.
Facciamo la controprova, impartendo il comando con un solo
argomento:
$ avi-delay prova.avi 
ritardo video (traccia 0): 0 ms
ritardo audio (traccia 1): 208.979591 ms
Va osservato che il programma non crea una copia del file,
ma si limita a modificare pochi byte del file esistente.
Tuttavia l'operazione e' sempre reversibile (basta ricordarsi
che valore di ritardo c'era prima).
Ad esempio, se ora diamo il comando:
$ avi-delay prova.avi 1 0  
tento di modificare il ritardo 208.979591 -> 0
tutto ok
il file e' tornato esattamente com'era prima.
Se invece di ritardare un audio, lo si vuole anticipare,
dobbiamo semplicemente ritardare il video della quantita'
opposta a quella desiderata. Ad esempio, se vogliamo
anticipare l'audio di 200 ms, daremo questo comando:
$ avi-delay prova.avi 0 200
tento di modificare il ritardo 0 -> 200
tutto ok
$ avi-delay prova.avi 
ritardo video (traccia 0): 200 ms
ritardo audio (traccia 1): 0 ms
Dobbiamo pero' stare attenti che almeno uno degli stream
abbia un ritardo impostato a 0.
Adesso spiego quali vantaggi ha questa utility rispetto a
usare l'opzione "-audio-delay" di mencoder:
- effettua il lavoro in una frazione di secondo, ed e'
  quindi molto piu' veloce (mencoder e' costretto a generare
  una copia di tutto l'AVI, e, se questo e' molto grande,
  occorrono alcuni minuti e naturalmente occorre avere
  lo spazio sufficiente a contenere anche la copia...);
- e' piu' preciso (le formule che usa mencoder sono
  troppo rozze e in alcuni casi effettua delle
  approssimazioni eccessive, che non sono necessarie);
- lavora senza problemi anche su multi-audio (mencoder,
  quando crea una copia, puo' aggiungere solo un audio,
  ed e' molto scomodo doverne aggiungere con successive
  copie tramite "avimerge").
Se qualche utente linux lo prova e incontra problemi, me
lo faccia sapere.

   copie tramite "avimerge").
sarebbe ideale se lo postassi sulla lista dedicata a mplayer, magari può 
esservi aggiunto senza troppi smanettamenti...
-- 
Ave!
Caesar.
Eatvr quo nos deorvm ostenta vocant. Alea iacta est!
Caivs Ivlivs Caesar, Imperator Mvndi
CaesarOd...@Fastwebnet.It

 esservi aggiunto senza troppi smanettamenti...
aggiunto a mencoder?
Be', mencoder ha gia' quella feature, l'unica cosa che avrebbe senso e'
migliorare la precisione della formula per calcolare il ritardo da
impostare.
Se intendi dire che anche mencoder (o mplayer) dovrebbe permettere di
impostare i ritardi al volo (senza creare copie), direi che questo
contrasta con l'impostazione del loro progetto:
mplayer e' un player, e come tale tratta i suoi input come file a sola
lettura;
mencoder e' il compagno di mplayer (con cui condivide il front-end),
e accetta in input tutto cio' che accetta mplayer, ed e' proprio
una scelta basilare di progetto che l'input sia a sola lettura
(l'input puo' essere anche lo standard input, oppure dati che
arrivano mediante un socket da un'altra macchina).

 contrasta con l'impostazione del loro progetto:
beh, pure questo non sarebbe male, ma in effetti non ho pensato che 
potesse non essere compatibile con le caratteristiche di mplayer... 
anche se magari mettere un'opzioncina --input-overwriting non sarebbe 
poi un sacrilegio, considerando il risparmio in tempo di cui parlavi...
vabbè l'avevo solo buttata lì, *adoro* mencoder e vedo ogni possibile 
miglioramento come molto ben accetto ;)


 poi un sacrilegio, considerando il risparmio in tempo di cui parlavi...
questa sarebbe un'idea, ma sarebbero tante le feature mancanti e
piu' urgenti... pensa al fatto che, sebbene sia mplayer che mencoder
non abbiano problemi a prendere in ingresso file multi-audio e a
selezionarne uno a piacere, non e' possibile crearne uno in uscita.
A cio' si puo' ovviare tramite una utility esterna (avimerge di
transcode) ma perche' non lo mettono direttamente in mencoder?

 ancora provarci...
ok, questo l'ho trovato facilmente :-)
Per prima cosa ho cercato questa stringa :-)
$ find -name "*.c" -exec grep "Setting audio delay to" {} \;
Poi ho scoperto che era invece in un file header *.h, e
da questo sono giunto facilmente al file libmpdemux/muxer_avi.c
(il nome e' tutto un programma...)
Alla riga 291 di tale file c'e' questo assegnamento:
---------------------
s->h.dwStart = muxer->audio_delay_fix * s->h.dwRate/s->h.dwScale;
---------------------
La formula e' corretta, e' la stessa identica che ho usato io,
ma essendo s->h.dwStart intero avrebbe dovuto arrotondare
all'intero piu' vicino, tipo cosi':
s->h.dwStart = 0.5+muxer->audio_delay_fix * s->h.dwRate/s->h.dwScale;
Con questa semplice modifica, ricompilando, mencoder effettua le
stesse scelte del mio programma, quindi e' un po' piu' preciso...

 stesse scelte del mio programma, quindi e' un po' piu' preciso...
ottimo! ora non ti resta che segnalarlo agli sviluppatori ;)
