AVInaptic

AVInaptic

Frank Sinapsi

Abstract

AVInaptic è un programma con una semplice GUI (GTK+ 1.2) che analizza file di tipo AVI, ASF/WMV, MP4/MOV, Matroska (MKV), OGG, OGM e FLV, e mostra molte informazioni sulle caratteristiche tecniche (utili per prevedere se il filmato verrà letto dal proprio lettore stand-alone). Permette anche di fare semplici modifiche al volo, come impostare i ritardi (o anticipi) su tutte le tracce audio e modificare il FourCC; permette di estrarre qualsiasi traccia presente nel file (video, audio, sottotitoli, allegati); su richiesta dell'utente, può effettuare l'analisi dei DRF, cioè un'analisi completa dei parametri di quantizzazione usati nelle codifiche di tipo MPEG-4 ASP e AVC (H.264); infine permette di apportare semplici modifiche a sottotitoli SRT per migliorarne la compatibilità con i lettori stand-alone.
N.B. I formati diversi da AVI possono essere non ancora completamente supportati.

Contents

1  Introduzione
2  Installazione del programma
    2.1  Windows
    2.2  Linux
3  Uso di base
4  Dati critici
    4.1  Risoluzione
    4.2  Dimensione del file e indici OpenDML
    4.3  Tipo di contenitore
        4.3.1  OpenDML
        4.3.2  OpenDML indexes
        4.3.3  OpenDML multi-chunks
        4.3.4  rec-lists
        4.3.5  DivX Media Format
        4.3.6  Google
    4.4  Frame rate
    4.5  QPel
    4.6  GMC
    4.7  MPEG4 interlacciati
    4.8  Matrici di quantizzazione
    4.9  Packed bitstream
    4.10  Aspect ratio
    4.11  Ritardi impostati
    4.12  Interleave/Preload
    4.13  Frames nulli
5  Modifiche ai filmati
    5.1  Impostare ritardi sulle tracce audio
    5.2  Modificare il FourCC e il video handler
6  Demuxing
7  Statistiche e grafici
    7.1  Bitrate medio parziale
    7.2  Analisi dei DRF
8  Controllo di vincoli (profili)
    8.1  Buffer underflows
9  Supporto ai sottotitoli SRT
    9.1  Modifiche ai sottotitoli
        9.1.1  Riformattare le entries
        9.1.2  Limitare il numero di righe
        9.1.3  Effettuare una trasformazione lineare dei timestamps
        9.1.4  Appendere le entries di un altro file SRT
10  Ringraziamenti

1  Introduzione

AVInaptic è un programma con una semplice GUI (GTK+ 1.2), che analizza file di tipo AVI, ASF, WMV, Matroska (MKV), OGG, OGM e FLV e mostra molte informazioni utili per prevedere se il filmato verrà letto dal proprio lettore stand-alone, o per individuare le cause di una eventuale riproduzione non corretta dello stesso.
Il programma è rilasciato già compilato per i sistemi Windows e Linux.
Oltre all'analisi delle caratteristiche tecniche dei filmati, AVInaptic permette anche di effettuare le seguenti operazioni:
Lo scopo di questo documento è quello di fornire molte indicazioni sulle possibili cause di riproduzioni non corrette da parte dei lettori stand-alone, ma non di spiegare nei dettagli come occorra procedere per risolvere tali problemi. Per questo scopo, si rimanda alle numerose guide presenti in rete, o alle FAQ che si trovano nel sito di Giubbe: http://giubbe.altervista.org.

2  Installazione del programma

2.1  Windows

La prima volta che si installa il programma, è necessario scaricare il file avinaptic-*-full.zip che si trova sul sito http://fsinapsi.altervista.org, creare una nuova cartella a piacere, e decomprimere il contenuto dell'archivio su tale cartella.
In caso di aggiornamento di una versione precedentemente installata, sarà sufficiente scaricare il file avinaptic-*.zip dallo stesso sito (si noti la mancanza di "-full" dal nome del file) e sostituire il file avinaptic.exe in esso contenuto all'omonimo file della precedente versione.
Per disinstallare il programma, basterà cancellare la cartella in cui lo si è installato, e di esso non resterà alcuna traccia.

2.2  Linux

È necessario scaricare il file avinaptic.tar.gz dal sito http://fsinapsi.altervista.org e copiare il solo file "avinaptic" in una directory contenuta nel path (tipicamente si sceglierà di copiarlo in /usr/local/bin).
Se l'esecuzione non parte, allora è probabile che nel sistema manchi qualche libreria dinamica utilizzata dal programma.
Per conoscere le librerie mancanti si esegua questo comando da una finestra di terminale:
ldd avinaptic
e si controlli quali sono le librerie che non vengono trovate dal linker.
In caso di dubbi su quali pacchetti occorra installare, contattatemi indicando la lista delle librerie che risultano mancarvi.

3  Uso di base

Innanzitutto, vorrei rassicurare che quando si apre un qualsiasi file con AVInaptic, viene sempre aperto in sola lettura, quindi non può venire modificato. Per modificarlo, occorre sempre che l'utente lo chieda esplicitamente e confermi di volerlo modificare (ad esempio, per impostare i ritardi o cambiare il FourCC). Naturalmente questo vale anche per i sottotitoli SRT.
Il programma ha due modalità di funzionamento: una veloce e una lenta. Di default, quando si apre un file con AVInaptic, viene usata la modalità veloce, il che vuol dire che si dovrebbe ottenere un rapporto tecnico in un tempo abbastanza breve. Se le informazioni ottenute con la modalità veloce sono sufficienti, allora non c'è bisogno di fare altro. Altrimenti, nei soli casi in cui gli stream video sono di tipo MPEG-4 ASP o AVC, è possibile richiedere un'analisi più approfondita, cliccando sul menu Statistiche->Analisi_DRF (oppure sull'analogo pulsante); in questo modo inizierà un'analisi del bistream che potrebbe durare alcuni minuti, al termine della quale verrà generato un nuovo rapporto, più completo del precedente.
Il rapporto attualmente visualizzato nella finestra principale può essere salvato in un file di testo, cliccando sul menu File->Salva_il_rapporto_come... (oppure sull'analogo pulsante). Nel file di testo vengono salvate tutte e sole le informazioni che sono visualizzate nella finestra, quindi si potranno ottenere risultati diversi a seconda che sia stata scelta la modalità veloce oppure lenta.

4  Dati critici

In questa sezione passiamo in rassegna tutti i dati di un filmato che dovremmo controllare e su cui eventualmente intervenire per massimizzare la probabilità che venga riprodotto correttamente dal proprio lettore stand-alone.
Va tenuto presente che non tutti i lettori stand-alone presentano le stesse limitazioni. In linea generale, queste dipendono:
Pertanto, può accadere che nello stesso lettore si presentino problemi che non si presenterebbero dopo un aggiornamento del firmware, anche se, come regola generale, non c'è da aspettarsi miracoli da nuove versioni del firmware.

4.1  Risoluzione

La maggior parte dei lettori stand-alone non riproduce filmati con risoluzione superiore a 720x576, quindi questo è il primo dato che dovremmo controllare. È molto improbabile che un filmato abbia più di 576 righe, ma può capitare che abbia una larghezza superiore a 720 (ad esempio: 768), quindi, tipicamente basta controllare che la larghezza non superi 720. In caso contrario, occorrerà ricodificare il filmato, applicando un filtro di tipo "resize" (tipo Bicubic, Lanczos ecc.).

4.2  Dimensione del file e indici OpenDML

La massima dimensione che può avere un file AVI sarebbe di 2 GB, ma mediante l'utilizzo delle estensioni OpenDML (le cui specifiche risalgono al 1996) è possibile creare AVI che superano ampiamente questo limite. In questo caso occorre però, quantomeno, usare nell'AVI dei tipi di indici diversi da quelli normali; indichiamo tali tipi di nuovi indici come "indici OpenDML".
Non tutti i lettori stand-alone supportano gli indici OpenDML, anzi, personalmente non ne conosco nessuno.
Quindi si verifichi se il proprio lettore li supporta e, in caso negativo, si provveda splittando l'AVI (se questo è più grande di 2 GB) e salvando le parti senza usare indici OpenDML.
Un AVI può avere indici OpenDML anche se è più piccolo di 2 GB.
In ogni caso, la presenza di tali indici viene segnalata da AVInaptic nelle "Info generiche" ("Tipo di contenitore").

4.3  Tipo di contenitore

I lettori stand-alone, di solito, leggono solo filmati MPEG4 in contenitori AVI (con qualche eccezione). Questi file, solitamente, hanno un nome che termina con l'estensione ".avi" oppure ".divx", ma AVInaptic li riconosce in base al contenuto, mostrandone il tipo alla voce "Tipo di contenitore".
Occorre fare attenzione alle possibili varianti dei file di tipo AVI, perché non tutte vengono supportate dai lettori stand-alone. Nei casi non supportati, occorrerà rimuxare il filmato (operazione che richiede poco tempo).
Oltre a riportare il tipo "AVI", AVInaptic potrebbe riportare una o più delle seguenti specificazioni:
Discutiamole brevemente, una per una.

4.3.1  OpenDML

Se il tipo riportato è soltanto "AVI" o soltanto "AVI OpenDML", allora è molto probabile che il lettore lo legga; nel secondo caso, vuol dire che è presente qualche estensione OpenDML, ma in genere può essere ignorata senza alcun effetto sulla riproduzione.

4.3.2  OpenDML indexes

Questo è un caso dubbio. Vuol dire che sono presenti indici OpenDML. Tipicamente, i muxers AVI scrivono anche gli indici nel vecchio standard1, ma anche in tal caso non è detto che essi siano completi e corretti; in caso contrario, non è detto che il lettore legga quelli OpenDML.

4.3.3  OpenDML multi-chunks

In questo caso, il filmato è stato memorizzato su più di un chunk RIFF, ed è quasi certo che si avranno problemi: anche se sembra che la riproduzione avvenga bene, si potrà fare il seeking solo all'interno del primo chunk RIFF (stessa cosa per gli avanzamenti veloci). Quando finisce la riproduzione del primo chunk, potrà succedere di tutto... ad esempio, il blocco della riproduzione. In questo caso occorre rimuxare in modo da ottenere un AVI con un solo chunk RIFF: se la dimensione del filmato supera 2 GB, occorrerà splittarlo in più parti, in modo che ciascuna parte abbia una dimensione inferiore a tale limite.

4.3.4  rec-lists

Questo formato, sebbene previsto dalle specifiche ufficiali AVI, non è supportato dalla maggior parte dei lettori stand-alone. Nel caso in cui si abbia a che fare con un filmato di questo tipo e si vogliano evitare rischi, sarà sufficiente rimultiplexarlo (ovviamente, senza usare le rec-lists).

4.3.5  DivX Media Format

Questo vuol dire che l'AVI contiene estensioni (non standard) introdotte dalla DivX Networks. Di solito i lettori stand-alone riescono a leggere questo tipo di file, ignorando le estensioni.

4.3.6  Google

Si tratta dei filmati scaricati da "Google Video", e sono caratterizzati da un chunk (non previsto dalle specifiche ufficiali AVI), che solitamente viene inserito nelle posizioni iniziali dell'AVI. Molti lettori stand-alone non riproducono questo tipo di filmati, quindi occorre rimultiplexarli in modo da eliminare il chunk fastidioso. Alternativamente, è possibile risalvare il filmato con AVInaptic, mediante la funzione di menu Misc->Salva_senza_'Google'.

4.4  Frame rate

Il frame rate di un filmato è il numero di frame (cioè, fotogrammi2) che sono presenti nel file per rappresentare un secondo di filmato.
Tipicamente i lettori stand-alone vengono collegati al televisore tramite un cavo "Scart", attraverso il quale gli inviano un segnale PAL, composto da 50 semiquadri al secondo.
Quindi, il frame rate di un filmato "ideale" per poter essere visto su un lettore stand-alone è 25, in modo che ciascun semiquadro PAL venga costruito esattamente dalle righe pari o dispari di ciascun frame del filmato.
Tuttavia, la maggior parte dei lettori si comporta in modo decente anche con valori di framerate diversi da 25 (in particolare, altri valori in cui è facile imbattersi sono 29.97 e 23.976, provenienti dallo standard NTSC). Se il vostro lettore "scatta" in modo particolarmente evidente e fastidioso su frame rate diversi da 25 (ad esempio, 23.976), allora dovrete convertire preventivamente il frame rate del filmato in 25 fps. La conversione da 23.976 a 25 è molto facile e può essere eseguita senza dover ricodificare il filmato, semplicemente accelerandolo un po'.

4.5  QPel

Questa feature (QPel sta per "Quarter Pixel Motion Compensation") è supportata dai chipset Mediatek, ma non da ESS Vibratto II (né dai precedenti), quindi, nel caso in cui venga rilevata e si sappia che il nostro lettore non la supporta, è necessario ricodificare il filmato.

4.6  GMC

Per questa feature (GMC sta per "Global Motion Compensation"), i lettori con chipset Mediatek e ESS Vibratto II si comportano allo stesso modo: i filmati codificati con GMC di DivX vengono letti; quelli codificati con GMC di XviD, non vengono letti.3 Esistono anche lettori che non leggono GMC per niente.4 Purtroppo, anche nei casi di GMC non supportati dal lettore, è necessario ricodificare il filmato.

4.7  MPEG4 interlacciati

È molto raro che un filmato realmente interlacciato (cioè, in cui le righe pari e dispari appartengono a "campi" riferiti a istanti temporali diversi) venga codificato in DivX (o XviD) senza prima essere "deinterlacciato" (cioè, filtrato da un algoritmo che interviene sulle linee che producono le fastidiose segmentazioni in corrispondenza delle parti in movimento nella scena).
Tuttavia, i codec MPEG4 ASP, al pari di quelli MPEG2, supportano un tipo di codifica interlacciata.
Può quindi capitare di imbattersi in filmati che usino questo tipo di codifica, indipendentemente dal fatto che siano o meno realmente interlacciati (cioè, può capitare che, per errore, un filmato progressivo sia stato codificato attivando la codifica interlacciata).
Esistono lettori, come il mio, che non riproducono correttamente filmati di questo tipo, quindi, in tali casi occorre ricodificare.

4.8  Matrici di quantizzazione

Le matrici di quantizzazione sono usate da un encoder MPEG4 per decidere come vanno approssimate le componenti di ogni blocchetto 8x8 di cui consistono le immagini. Le matrici sono due: una viene usata per la codifica dei frame di tipo I (intra), l'altra per gli altri tipi di frame (inter). Ogni matrice ha dimensione 8x8, pertanto è costituita da 64 numeri (interi). Le matrici di quantizzazione più largamente usate con i codec di tipo MPEG4 si chiamano H.263 (prendono il nome dall'omonimo standard di codifica dell'ITU-T). Lo standard MPEG4 Visual, però, consente di usare, al posto di H.263, sia le matrici predefinite che si chiamano MPEG, che matrici del tutto arbitrarie, a scelta dell'utilizzatore del codec; queste ultime vengono indicate come matrici "MPEG custom". Le matrici H.263 e MPEG, essendo note, non vengono memorizzate esplicitamente nel bitstream MPEG4 (viene utilizzato un solo bit per le prime, e tre bit per le seconde), mentre quelle MPEG custom vengono memorizzate per intero in una struttura chiamata "header VOL" (Video Object Layer), che viene replicata nel bitstream all'inizio di ogni frame di tipo I.
Come è facile intuire, un decoder MPEG4, quando ricostruisce le componenti delle immagini dalle componenti approssimate, dovrà usare le stesse matrici di quantizzazione che aveva usato l'encoder.
Alcuni lettori stand-alone non supportano matrici di quantizzazione diverse da H.263, quindi non possono riprodurre filmati di tale tipo, e nei casi in cui lo fanno, usando la matrice H.263 al posto di quella corretta ottengono delle immagini con blocchi particolarmente evidenti. In tali casi, è necessaria la ricodifica.

4.9  Packed bitstream

In un bitstream MPEG4, i frame sono codificati in strutture chiamate VOP (Video Object Plane). In un bitstream normale (unpacked), c'è una corrispondenza biunivoca tra frames e VOP, ma in un packed bitstream possono esserci due VOP per alcuni frame.
I primi lettori stand-alone con chipset Mediatek non gestivano correttamente i filmati codificati con XviD in packed bitstream, e, a causa di ciò, "scattavano". Questo problema può essere risolto mediante l'aggiornamento del firmware a versioni più recenti.
Tuttavia, nel caso che si avessero ancora problemi con questo tipo di filmato, è possibile riscrivere un packed bitstream in formato unpacked, senza dover ricodificare il filmato. Sotto Windows tale operazione può essere fatta dal programma MPEG4 Modifier. Sotto Linux, da MP4Box (pacchetto gpac), oppure da Avidemux2, oppure da UnpackCL.

4.10  Aspect ratio

Questo dato (tradotto in italiano con "rapporto di forma") indica il rapporto tra la larghezza (o "base") e l'altezza del filmato. Per dissipare ogni possibilità di confusione, è opportuno dare le seguenti definizioni:
Il contenitore AVI originario non prevede una memorizzazione del DAR (né del PAR), mentre il FAR è implicitamente ricavabile dalla risoluzione; quindi, la situazione di default è che DAR=FAR (cioè, PAR=1), e questa è la regola seguita dai lettori stand-alone con gli AVI/MPEG4 (anche se alcuni lettori, con alcune risoluzioni ben precise, assumono un DAR diverso dal FAR).
Quando PAR=1, si dice anche che il "pixel è quadrato".
Tutti gli stream MPEG (MPEG-1/2/4) prevedono la memorizzazione del PAR (e MPEG4 Modifier permette di modificare proprio tale campo), tuttavia, per quanto riguarda MPEG4, si è consolidata l'abitudine (forse per colpa dell'AVI) di non rispettare tale valore (e assumere che DAR=FAR), anche se alcuni player per PC lo rispettano.
Per quanto riguarda MPEG-1/2, invece, il PAR memorizzato viene sempre rispettato.
Per fare un esempio significativo, nel SuperVCD la risoluzione è 480x756, ma il DAR è 4:3, quindi abbiamo:
FAR=480/576=0.833333
DAR=4/3=1.333333
PAR=1.6
In questo caso, il PAR è 1.6 (i pixel sono "rettangolari").
Esiste un'altra possibilità di memorizzare il DAR in un AVI, ed è fornita da una estensione OpenDML chiamata "Video Property List" (si tratta di un header che può essere opzionalmente inserito nell'AVI). Sfortunatamente neanche questa informazione viene rispettata dalla maggior parte dei lettori in circolazione.
In conclusione, nel caso in cui il filmato abbia una risoluzione che non corrisponde al pixel quadrato (PAR=1) e che si sappia che il proprio lettore stand-alone non rispetti nessuno dei metodi discussi in questa sezione, non resta altro che ricodificarlo, applicando un filtro di resize in modo opportuno.

4.11  Ritardi impostati

[...]

4.12  Interleave/Preload

[...]

4.13  Frames nulli

Il contenitore AVI permette di inserire, a un livello gestito dal contenitore stesso (cioè, al di fuori del bitstream) due tipi di frames fittizi: drop frames e delay frames.
Questi tipi di frames sono molto rari nei filmati in cui ci si imbatte abitualmente, che di solito sono ottenuti da DVD, perché in tali casi è abbastanza improbabile che un encoder abbia un motivo per inserirli (a meno di avere impostato una codifica a bitrate estremamente bassi, e il codec non riesca a rispettarli nemmeno quantizzando al massimo).
Però, possono capitare in filmati che provengono da un processo di acquisizione in tempo reale: in tali casi, vincoli temporali possono, di tanto in tanto, costringere un programma a rinunciare a codificare un frame, sostituendolo con un frame nullo, che ha lo scopo di mantenere il video sincronizzato con l'audio.
Quando un player incontra un frame nullo non deve fare niente di speciale: deve semplicemente attendere il tempo della durata di un frame, e passare a visualizzare il frame successivo (in tal modo, il frame precedente permane sullo schermo per un tempo doppio di quello normale).
Alcuni lettori stand-alone rispettano i frame nulli, ma alcuni li ignorano tranquillamente; in altre parole, il frame che precede il frame nullo, non resta sullo schermo per un tempo doppio, ma viene sostituito da quello successivo al frame nullo, nell'intervallo di tempo che sarebbe ad esso riservato. Questo comporta uno "slittamento" in anticipo dello stream video su quello audio, quindi, se i frame nulli non sono pochissimi, si avrà come effetto una percepibile asincronia audio/video (se il framerate è 25 fps, bastano 3 frame nulli non rispettati perché l'audio risulti in ritardo di 120 ms, che è un grado di asincronia già percepibile come fastidioso dalla maggior parte delle persone).
Se si presenta questo problema, la soluzione è quella di ricodificare il filmato, facendo in modo che i frame nulli vengano codificati all'interno del bitstream. Nel programma MEncoder, basterà usare il filtro video -vf harddup.

5  Modifiche ai filmati

5.1  Impostare ritardi sulle tracce audio

[...]

5.2  Modificare il FourCC e il video handler

[...]

6  Demuxing

[...]

7  Statistiche e grafici

7.1  Bitrate medio parziale

Iniziamo con delle semplici definizioni.
Il bitrate medio (bm) di un filmato è definito come il numero medio dei bit che vengono usati per rappresentare un secondo di filmato; è quindi il rapporto tra la dimensione (in bit) del bitstream e la durata (in secondi) del filmato. Dato che la durata è il rapporto tra il numero totale dei frame e il frame rate, abbiamo:

bm= (bitstream size) (frame rate)

nframes

 
Il bitrate si misura in bps (bit per secondo), ma spesso si preferisce esprimerlo in kbps, dove la costante k vale 1000 (non 1024, come si potrebbe supporre).
Il bitrate medio parziale all'istante t non è altro che il bitrate medio del filmato il cui inizio coincide con il filmato totale, ma che finisce all'istante t.
Il programma può creare e mostrare, su richiesta dell'utente, il grafico del bitrate medio parziale del filmato analizzato.
Tale grafico mostra, istante per istante, la situazione in cui si trovava il codec mentre generava il bitstream: tale parametro gioca un ruolo importante nel meccanismo di "rate control" del codec, influendo sulla scelta dei "quantizers" da usare. I "quantizers" rappresentano il grado di approssimazione delle immagini; tanto più alti saranno, quanto più degradata risulterà l'immagine. Il "quantizer" viene anche chiamato DRF (Detail Removal Factor).
Il grafico del bitrate medio parziale ha una proprietà interessante: se partiamo da uno stesso filmato e lo codifichiamo prima a quantizer costante, poi a target bitrate in doppia passata, i grafici dei risultati che otteniamo hanno quasi la stessa forma.
In realtà, i due grafici possono presentare lievi differenze, perché le stime effettuate dal codec possono essere un po' inaccurate, costringendo il meccanismo di rate control a un'oscillazione nella scelta dei quantizers;5 effettuando ulteriori passate, si ottengono approssimazioni più precise, ma in genere la differenza tra una passata superiore alla seconda e la precedente è del tutto trascurabile rispetto alla differenza tra la seconda e la prima.
[...]

7.2  Analisi dei DRF

[...]
Nei codec MPEG-4 ASP (DivX, XviD, Lavc, 3ivx, ecc), il quantizer è un numero compreso tra 1 e 31, e generalmente, i valori che corrispondono a un'approssimazione normale (senza troppa perdita di qualità) sono nell'intervallo 2-5.
Nei codec MPEG-4 AVC (x264, ateme, ecc), il quantizer è un numero compreso tra 0 e 51, e generalmente, i valori che corrispondono a un'approssimazione normale sono nell'intervallo 18-30.
Quindi, nel caso AVC (H.264), è normale avere quantizer molto più alti rispetto al caso ASP.
Il motivo di questa differenza è dovuto al fatto che in H.264 hanno introdotto una trasformata differente, e un diverso modo di quantizzare i coefficienti che risultano dalla trasformata.
Una trasformata è un'operazione matematica che viene eseguita su un "blocco" (un quadratino che fa parte di un'immagine), cioè un'operazione del tipo:

X® A·X·At
dove A è una certa matrice e At è la sua trasposta.
(N.B. questa operazione è reversibile)
Questa operazione serve per trasformare un'immagine nei coefficienti di una combinazione lineare di una "base". Una delle basi più usate nell'ambito della codifica di file multimediali è la cosiddetta "base DCT" (trasformata discreta del coseno), usata sia nelle JPEG che nei codec video MPEG.
dct-basis.png
Come si vede, si tratta di 64 quadratini 8x8. Ebbene, tutte le immagini 8x8 a livelli di grigio possono essere scritte come combinazione lineare di questi 64 quadratini.6
Quando si applica la trasformata DCT, si ottengono proprio i "pesi", che in questo caso si chiamano "coefficienti DCT".
Uno può pensare: prima avevamo un'immagine 8x8 (64 numeri); dopo la trasformata abbiamo 64 coefficienti (64 numeri). Quindi che risparmio abbiamo in termini di spazio di memorizzazione? Nessuno.
Però, ci sono due punti importanti da osservare.
Il primo è che si dà il caso che la nostra percezione visiva non funziona allo stesso modo sulle 64 immaginette della base DCT, quindi, se vogliamo apportare delle approssimazioni all'immagine (per risparmiare spazio di memorizzazione), lo possiamo fare sacrificando l'accuratezza nella precisione dei coefficienti in modo proporzionale alla loro "importanza". Quindi, inizieremo a sacrificare i coefficienti che rappresentano componenti delle immagini che corrispondono a dettagli che tipicamente tendiamo a percepire meno. Il criterio con cui approssimiamo le componenti è basato su un modello del "sistema visivo umano", ed è sintetizzato dalle cosiddette "matrici di quantizzazione" (ad esempio, XviD permette di definire matrici a piacere). Oltre alle matrici di quantizzazione, il grado di approssimazione è regolato da un parametro (un numero); questo numero è proprio il "quantizer" di cui stiamo parlando.
Il secondo punto importante è che le immagini "realistiche" (quelle che provengono dal mondo) non sono miscugli casuali di colori, ma hanno caratteristiche statistiche significative. A causa di ciò, succede che i coefficienti DCT di un'immagine realistica siano "addensati" in una zona della matrice; in altre parole, è raro che un'immagine del mondo reale abbia tutte le componenti DCT, ma ne avrà solo un sottoinsieme abbastanza compatto. Quindi molti coefficienti saranno nulli, e quelli non nulli saranno perlopiù disposti vicini l'uno all'altro. Per questo, è stato introdotto un particolare riordinamento dei coefficienti (chiamato "zigzag scan"), che genera una sequenza di bit che viene compressa abbastanza bene mediante una codifica entropica (la sequenza contiene sotto-sequenze aggregate di zeri). Ricollegandomi al punto precedente, quando si approssimano anche i coefficienti non nulli (il grado di approssimazione dipende dalle matrici di quantizzazione e dallo specifico quantizer), succede che il numero di bit diversi da 0 siano sempre meno, rendendo la sequenza sempre più comprimibile.
[...]

8  Controllo di vincoli (profili)

[...]

8.1  Buffer underflows

I parametri essenziali che caratterizzano i vincoli vbv sono due: la massima velocità di lettura (max_rate) e la dimensione del buffer di lettura (buf_size). Ci sarebbe un terzo parametro (buf_init) che indica il livello iniziale di pre-riempimento del buffer, ma è meno importante (basta che questo venga impostato a un valore sufficiente a non provocare underflow iniziali; per dare un'idea, un valore sufficiente può essere qualsiasi valore compreso tra (0.75 * buf_size) e buf_size).
Il parametro più determinante è max_rate, che indica il limite massimo di velocità di lettura di un apparecchio; il parametro è espresso in bits al secondo. Questo può essere visto come il massimo bitrate che può avere il filmato, dato che, se il filmato avesse un bitrate superiore a tale limite, l'unità di lettura dell'apparecchio non riuscirebbe a trasferirlo in tempo utile per la sua corretta decodifica e visualizzazione.
Ma cosa significa che il "massimo bitrate del filmato" non deve superare max_rate? Cosa si intende con "massimo bitrate del filmato"?
Non si intende il bitrate medio dell'intero filmato (quello che viene riportato dai vari programmi di analisi), anche se certamente questo valore deve essere inferiore a max_rate, altrimenti esiste sicuramente almeno una zona del filmato che ha un bitrate superiore a max_rate. Non si intende nemmeno il "bitrate istantaneo", se con questo termine ci riferiamo al bitrate di ogni singolo frame del filmato, perché le dimensioni dei frame variano molto fra loro (proprio a causa del tipo di codifica, che prevede che alcuni frame vengano presi come riferimento da altri). Si intende invece il bitrate medio calcolato non sull'intero filmato, ma su ogni intervallo temporale di una certa ampiezza, che viene fatto variare su tutta la durata del filmato. In altre parole, si fissa una certa ampiezza (per fissare le idee, supponiamo di fissarla a mezzo secondo), dopodiché si considerano tutti i possibili segmenti del filmato lunghi mezzo secondo, e si calcola il bitrate medio di ogni segmento. Tale bitrate medio non deve superare il max_rate. È chiaro che il massimo bitrate medio calcolato su intervalli di mezzo secondo è maggiore o uguale al bitrate medio di tutto il film, e questo giustifica la mia affermazione di sopra secondo cui il bitrate medio totale deve essere necessariamente inferiore a max_rate.
Il secondo parametro (buf_size) serve proprio a fissare l'ampiezza degli intervalli su cui calcolare il bitrate, ma questo lo spiegherò meglio nel seguito.
Facciamo un po' di esempi pratici, in modo da chiarire questi concetti.
Per prima cosa impariamo a mettere in relazione le dimensioni dei frames con i bitrates. I bitrates sono espressi in bits/s (bits al secondo) o bps, anche se spesso è conveniente esprimerli in kbps, dove la lettera k sta per "mille"; quindi, ad esempio, 3000 kbps significa "3 milioni di bits al secondo". I bitrates possono essere visti come "velocità di trasferimento di informazioni", cioè "quanti bits vanno trasmessi nell'unità di tempo".
Ogni frame di un filmato viene codificato (in divx o altri codecs) mediante una certa sequenza di bits. Il numero di tali bits è la lunghezza (in bits) del frame. Ad esempio, un frame potrebbe essere codificato da una sequenza di 1145648 bits, quindi diremo che è lungo 1145648 bits, oppure 143206 bytes (1 byte = 8 bits).
Quando un lettore divx dovrà mostrare sullo schermo quel frame, per prima cosa dovrà effettuare il trasferimento dal supporto in cui è memorizzato a una sua struttura interna (un buffer di lettura), quindi dovrà trasferire quei 143206 bytes dal supporto al suo buffer interno. In quanto tempo dovrà riuscire a effettuare tale trasferimento? Nel tempo in cui resta visualizzato ciascun frame. Nel sistema PAL, un segnale è composto da 50 semiquadri alternati al secondo, il che corrisponde a 25 quadri al secondo, quindi al framerate di 25 fps (fps = frame per secondo). Pertanto, il tempo in cui resta visualizzato ciascun frame è "un venticinquesimo di secondo", o 40 ms (40 millisecondi), o 0.04 secondi.
A questo punto conosciamo la strada da percorrere (1145648 bits), e sappiamo in quanto tempo va percorsa (0.04 secondi), quindi possiamo calcolare la velocità necessaria a effettuare questo viaggio: basta dividere 1145648 per 0.04 e otteniamo: 28641200 bps, o 28641 kbps.
Quindi, per riuscire a trasferire quel frame (143206 bytes) in 0.04 secondi dal supporto alla sua memoria interna, l'unità di lettura dell'apparecchio dovrebbe avere una velocità di lettura almeno pari a 28641 kbps. Si tratta di una velocità molto elevata, forse nettamente superiore alle possibilità dei lettori divx attualmente in commercio.
Questo vuol dire che i lettori divx non possono leggere filmati che hanno frame di quelle dimensioni (143206 bytes)?
Non necessariamente!
Infatti, se vi divertite ad analizzare divx a risoluzioni non troppo basse (tipo 720x576), può capitare benissimo che abbiamo dei frame I anche più grossi di 143206 bytes, eppure, può capitare che la maggior parte dei lettori da tavolo riescano a leggere tali filmati in modo fluido, senza problemi di sorta.
Allora questo vuol dire che i lettori da tavolo riescono a trasferire dati dal supporto alla loro memoria interna a una velocità superiore a 28000 kbps?
Nemmeno questo!
Allora come si spiega tutto ciò?
Semplice: la memoria interna del lettore è un buffer, una struttura che serve proprio ad "ammorbidire" le fluttuazioni nelle dimensioni di frame che si susseguono nel filmato. Anche se un frame grosso (come quello di 143206 bytes) viene letto in un tempo ben maggiore di 0.04 secondi, la maggior parte degli altri frames ha una dimensione molto più piccola, e viene trasferita in tempi ben minori di 0.04 secondi (ciascuno) quindi il tempo che viene risparmiato dai frame piccoli può essere sfruttato per il trasferimento di quelli grossi. Quello che fa il lettore è semplicemente di "caricare" il buffer prima di iniziare la riproduzione, dopodiché l'unità di lettura cercherà di mantenere il buffer più pieno possibile (trasferendoci via via i dati dal supporto) e il decoder vero e proprio prenderà i frame dal buffer (lo spostamento di dati tra strutture interne all'apparecchio è molto veloce e, paragonato al trasferimento dal supporto, può essere considerato istantaneo). Quindi, quello che veramente importa è che, quando il decoder ha bisogno di leggere il prossimo frame (questo succede ogni 0.04 secondi), tale frame sia già stato tutto trasferito (dall'unità di lettura) dal supporto al buffer.
Un altro modo di vedere le cose è il seguente: ciò che importa è che l'intervallo di filmato presente nel buffer abbia un bitrate medio non superiore alla massima velocità di trasferimento dell'unità di lettura.
Per fissare le idee, supponiamo che un lettore da tavolo riesca a trasferire dati da un supporto a una velocità di circa 10000 kbps, e che abbia un buffer di lettura capace di contenere mezzo secondo di filmato. Quanto sarà grande il buffer? Be', è banale. Se dovesse contenere un secondo, nel caso limite vengono trasferiti 10000 kbits (10 milioni di bits), quindi la capienza del buffer è di 5 milioni di bits, cioè 625000 bytes.
Se le dimensioni dei frames del filmato fossero tutte uguali, quale sarebbe la dimensione massima consentita per non avere problemi? E, in quel caso particolare, quanti frames potrebbe contenere il buffer? Magari prima calcolatelo per conto vostro come esercizio e poi controllate il risultato.
Be', la risposta è semplice: 10000k * 0.04 = 400000 bits = 50000 bytes. Il buffer quindi potrebbe contenere 12 frames e mezzo (625000/50000). Del resto si poteva osservare che 25 frames corrispondono a un secondo, quindi, se il buffer contiene mezzo secondo di filmato, nel caso in cui i frame hanno tutti la stessa dimensione, dovrà contenere 12 frames e mezzo.
Ma in realtà, come sappiamo bene, i frames non hanno mai la stessa dimensione. Anzi, nel caso tipico, abbiamo sequenze che sono fatte così: prima abbiamo un frame I che tipicamente è abbastanza voluminoso (è una specie di JPEG), seguito da frame di tipo P e B che, potendo sfruttare le ridondanze temporali tra frame della stessa sequenza (potendo cioè sfruttare informazioni codificate in precedenza nei frame di riferimento) sono più piccoli dei frame I (i P sono tipicamente più piccoli dei frame I, e i B tipicamente sono ancora più piccoli dei P).
Quindi, vedete che alla fine non è obbligatorio che tutti i frame del filmato debbano essere più piccoli della dimensione che corrisponde alla velocità di lettura dell'apparecchio. Ad esempio, come abbiamo visto, un lettore che abbia una velocità di lettura pari a 10000 kbps (che corrisponde a una dimensione media di frame pari a 50000 bytes) e che abbia un buffer di 625000 bytes, può benissimo "reggere" anche frame grossi (come 143206 bytes, che corrisponde a quasi il triplo del max_rate) purché i frame che gli stanno vicini siano più piccoli di 50000 bytes, per compensare quel picco isolato. Più precisamente, la condizione che deve soddisfare il filmato è questa: se noi prendiamo tutte le possibili sequenze del filmato lunghe mezzo secondo, il bitrate medio di ciascuna sequenza non deve superare 10000 kbps.
E cosa succede se esiste una sequenza di mezzo secondo il cui bitrate medio supera 10000 kbps?
A questo punto non dovreste avere problemi a rispondere alla domanda.
Succede che si verificano i famigerati "buffer underflows"!
Perché l'unità di lettura bufferizzata può tollerare momentanei picchi di bitrate istantanei superiori alla sua velocità di trasferimento solo se questi sono "tamponabili" dal buffer. Se una sequenza di mezzo secondo ha un bitrate medio superiore a max_rate, la sequenza non può essere fisicamente trasferita dal supporto in mezzo secondo, quindi esisterà un istante ben preciso in cui il buffer resterà vuoto! E quando resterà vuoto, il decoder non potrà procedere alla decodifica e visualizzazione del film, quindi perdiamo la fluidità nella riproduzione del film.
Vediamo adesso nel dettaglio che cosa succede durante la riproduzione del filmato, dal punto di vista del buffer. Supponiamo che, quando arriva a essere decodificato un frame grosso (tipo 143206 bytes), il buffer sia pieno. Il buffer è pieno, quindi contiene il frame grosso (143206 bytes) che sarà il prossimo a essere estratto per essere decodificato, e i frame successivi, per i restanti 481794 bytes (625000-143206). A questo punto viene estratto il frame grosso, quindi il livello di occupazione del buffer diventa 481794 bytes (625000-143206). Nei successivi 40 millisecondi, accadono contemporaneamente due cose:
  1. il frame grosso viene decodificato e visualizzato;
  2. l'unità di lettura tenta di ri-riempire il buffer, cioè colmare il vuoto che si è formato dopo l'estrazione del frame grosso.
Trascorsi tali 40 millisecondi, il decoder ha bisogno di estrarre dal buffer il frame successivo. La domanda che dobbiamo porci è: in quei 40 millisecondi, ce l'ha fatta l'unità di lettura a colmare il vuoto lasciato dal frame grosso?
La risposta è: NO!
Perché l'unità di lettura, al massimo, ha potuto trasferire solo 50000 bytes (abbiamo supposto che max_rate=10000000 bps), quindi, il suo livello si è potuto portare da 481794 a 531794 bytes, mentre la capacità massima del buffer abbiamo supposto essere 625000 bytes.
Questo è l'effetto causato dal frame grosso: ogni frame più grosso di 50000 bytes (corrispondente al max_rate) provoca una estrazione dal buffer che supera la quantità di dati che si riesce a inserire nel buffer in 40 millisecondi. In altre parole, in corrispondenza di frame più grandi di 50000 bytes, la velocità di svuotamento del buffer è superiore alla velocità di riempimento. Comunque, se il frame successivo a quello grosso è più piccolo di 50000 bytes, accade l'opposto: cioè, la quantità di dati reinseriti nel buffer (50000 bytes) è superiore a quella tolta, e quindi il livello di occupazione del buffer può risalire... Se ci sono troppi frame grossi (oltre 50000 bytes) nella stessa sequenza di mezzo secondo, in modo tale che la dimensione media di tale sequenza supera 50000 bytes, allora, in qualche punto della sequenza, il buffer resta vuoto e il decoder resta senza dati da decodificare!
Dopo tutta questa spiegazione dovrebbe risultare chiaro cosa sono:
  1. il max_rate specificato nel profilo selezionato;
  2. il buf_size specificato nel profilo selezionato;
  3. il buf_init specificato nel profilo selezionato;
  4. gli eventuali buffer underflows riportati nella sezione Profile compliancy.
Il max_rate è la massima velocità di trasferimento dell'unità di lettura del lettore da tavolo, espressa in bits al secondo. Come abbiamo visto, può essere vista come il massimo bitrate medio su "sequenze" del film. La dimensione di tali "sequenze" è data da buf_size. Nell'esempio che abbiamo visto, se max_rate=10000000, sequenze aventi un'ampiezza di mezzo secondo corrispondono a un buf_size pari a 5000000. In modo analogo, se il max_rate è 7000000 bps e il buf_size è 1000000 bits, il vincolo vbv può essere espresso dicendo che ogni sequenza di un settimo di secondo estratta dal film deve avere un bitrate medio non superiore a 7000 kbps.
Il parametro buf_init influisce poco sulla rilevazione degli underflows: come ho già scritto, lo si può settare allo stesso valore di buf_size, oppure a (0.75 * buf_size), oppure a (0.9 * buf_size). Il risultato non cambierà...
Per concludere, resta il problema più grosso: a quali valori occorre settare max_rate e buf_size affinché avinaptic segnali gli underflows che corrispondono effettivamente al proprio lettore da tavolo, evitando i falsi positivi e i falsi negativi?
Questo problema non ha una soluzione facile.
Nella versione di avinaptic del 07-10-2007 avevo messo come predefiniti i valori estratti dal profilo "Home Theater PAL", cioè: max_rate=4854000 bps e buf_size=3145728 (come ora sapete calcolare, tale buf_size corrisponde a circa 65 centesimi di secondo, cioè il vincolo è che ogni sequenza di 65 centesimi di secondo del film analizzato deve avere un bitrate medio non superiore a 4854 kbps).
Da prove sperimentali, sembra che questi valori siano troppo restrittivi per molti lettori da tavolo, nel senso che abbiamo trovato molti film che vengono letti in modo fluido da molti lettori da tavolo, ma su cui vengono riportati buffer underflows da avinaptic, utilizzando tale profilo...
Del resto abbiamo riscontrato differenze tra lettori diversi, cioè filmati che vengono riprodotti in modo fluido su un lettore, e non fluido (nei punti segnalati) su altri, quindi la conclusione è la seguente:
non esiste un profilo che vada bene per tutti i lettori.
Io ho un lettore che, sperimentalmente, sembra non avere problemi fino al vincolo max_rate=6000000, e inizia ad avere problemi con filmati che provocano segnalazioni di underflows impostando max_rate poco superiori a 6000000.
Però ho anche un altro lettore che sembra non avere problemi nemmeno con max_rate=12000000 bps che probabilmente ha un'unità di lettura più efficiente dell'altro.

9  Supporto ai sottotitoli SRT

Quando si apre un file di sottotitoli SRT, si ottiene un rapporto con i seguenti campi:

9.1  Modifiche ai sottotitoli

Se un file dovesse presentare qualche caratteristica che può essere fastidiosa, cliccate sul pulsante con la lettera "A" (oppure menu Misc->Modifica_i_sottotitoli). In questo modo le entries del file SRT verranno importate dentro tabelle del database SQL, e si aprirà una nuova finestra... vuota :-) perché ancora devo scrivere la GUI. Comunque, nella finestra vuota c'è un menu, che già adesso permette di fare le seguenti operazioni:
  1. rimuovere le entries vuote (ammesso che ci siano);
  2. rimuovere tutti i tags (ammesso che ci siano);
  3. rimuovere i commenti7 (ammesso che ci siano);
  4. riformattare le entries;
  5. limitare il numero di righe;
  6. effettuare una trasformazione lineare dei timestamps;
  7. appendere le entries di un altro file SRT;
  8. esportare le entries attuali in un nuovo file SRT (File->Salva_sottotitoli_come...).
Chiarisco un punto importante: le modifiche vengono apportate esclusivamente sul database (il file SRT di partenza non viene toccato); se si chiude quella finestra senza avere esportato su un nuovo SRT, le modifiche vengono perse ed è come se non fosse successo nulla.
Le operazioni dovrebbero essere abbastanza chiare, eccetto i punti 4, 5, 6 e 7, che vengono spiegate nelle prossime sezioni.
Naturalmente, dopo che si è salvato un nuovo file SRT, è possibile riaprirlo con AVInaptic per controllarne le caratteristiche (ed eventualmente modificarlo nuovamente).
Mi resta da dire che alcuni problemi del file di partenza potrebbero essere risolti automaticamente in modo trasparente, semplicemente risalvando il file: ad esempio, se ci sono timestamps scritti male (ma che il mio parser riesce a riconoscere lo stesso), il campo "Sintassi timestamps" sarà diverso da "OK"; nel nuovo file salvato dalla finestra vuota, tutti i timestamps saranno sicuramente scritti bene (inoltre, non ci saranno caratteri e linee superflue, la numerazione delle entries sarà sicuramente giusta, e la terminazione di linea sarà sicuramente ms-dos).

9.1.1  Riformattare le entries

Quando chiede di riformattare le entries, l'utente deve scegliere un valore che sarà la massima lunghezza consentita per ogni riga di testo. Il programma non farà altro che splittare le righe troppo lunghe (cioè, che superano quella soglia) accorpando le eccedenze con eventuali righe successive. Tuttavia non si tratta di una completa riformattazione (simile a quella effettuata da un programma di impaginazione di testo) perché questa operazione può solo aumentare il numero di righe (cioè, non può diminuirle accorpando righe più corte della soglia...).
Vediamo un esempio che chiarirà tutto.
Supponiamo che nel file ci sia questa entry:
339
00:25:03,160 -> 00:25:06,596
don't behave like a hoodlum! oh, honey, you do like making love with me, don't
you?
l'entry è costituita da due righe, la prima delle quali è lunga ben 78 caratteri (troppi per qualsiasi lettore stand-alone) e la seconda è cortissima (4 caratteri).
Se applichiamo l'operazione "Riformatta le righe" e impostiamo una soglia di 30, quando salveremo il nuovo SRT, ci troveremo questa entry così riscritta:
339
00:25:03,160 -> 00:25:06,596
don't behave like a hoodlum!
oh, honey, you do like making
love with me, don't you?
Tuttavia, se partiamo dalla nuova situazione, in cui la lunghezza delle righe è al massimo 30, e riapplichiamo la stessa operazione impostando una soglia di 50, non otteniamo alcun effetto. Perché questa operazione serve solo per splittare le linee troppo lunghe, non per allungare le corte (e diminuire il numero di righe).8

9.1.2  Limitare il numero di righe

Quando chiede di limitare il numero di righe per entries, l'utente deve scegliere un valore che sarà il massimo numero di righe consentito per ogni entry. Il programma interverrà soltanto sulle entries che hanno un numero di righe superiore alla soglia impostata, suddividendole nel minimo numero di entries necessario per rispettare il limite imposto. Questa operazione, quindi, avrà come effetto la creazione di nuove entries (a meno che tutte le entries abbiano già un numero di righe minore o uguale alla soglia). I timestamps delle entries ottenute mediante limitazione di righe, saranno riscritti in modo coerente con la suddivisione. In particolare, il tempo di partenza della prima entry generata coinciderà con il tempo di partenza della entry originale, mentre il tempo di arrivo dell'ultima coinciderà con il tempo di arrivo della entry originale. I tempi intermedi avranno valori intermedi, in misura proporzionale ai numeri relativi di righe di ciascuna entry generata.
Vediamo un esempio per chiarire i dettagli: se una entry ha 5 righe e si applica questa operazione specificando un massimo di 2 righe, tale entry viene suddivisa in 3 entries (ne vengono create due nuove).
Inoltre, se l'entry da 5 righe ha questi timestamps:
00:00:04,000 -> 00:00:06,000
la durata di 2 secondi viene suddivisa nel numero di righe (5), quindi, dato che le 5 righe vengono suddivise come 2+2+1, allora i nuovi timestamps diventano:
00:00:04,000 -> 00:00:04,800
00:00:04,800 -> 00:00:05,600
00:00:05,600 -> 00:00:06,000
In altre parole, le prime due entries resteranno visualizzate per 800 ms ciascuna, e la terza soltanto per 400 ms (perché ha una sola riga di testo).

9.1.3  Effettuare una trasformazione lineare dei timestamps

[...]

9.1.4  Appendere le entries di un altro file SRT

A volte capita di imbattersi in film che sono divisi in due parti, e anche i relativi file di sottotitoli SRT sono divisi, in modo coerente con i filmati. Se si desidera ottenere un unico filmato, esistono numerosi programmi che permettono di appendere il secondo filmato al primo. Per eseguire la stessa operazione anche sui sottotitoli SRT, si può procedere nel seguente modo:
Arrivati a questo punto, il programma ha bisogno di conoscere la durata della prima parte del filmato, quindi si aprirà una finestra che permette l'inserimento di tale dato. La durata può essere inserita esplicitamente, modificando a mano i campi della finestra, oppure, più comodamente, è possibile selezionare la prima parte del filmato: in tal modo, il programma estrarrà la durata dal filmato stesso e la inserirà automaticamente nei campi della finestra stessa. Una volta inserito il valore corretto, si dovrà confermare (pulsante "Ok"), dopodiché le entries del secondo SRT verranno appese ai sottotitoli correnti, con l'accortezza che i suoi timestamps saranno ritardati del valore specificato. Non resterà altro che salvare un nuovo SRT, che conterrà i sottotitoli completi e sincronizzati per l'intero film.

10  Ringraziamenti

Ringrazio per aver testato il programma e per gli utili suggerimenti le seguenti persone: Jan AxHell (che ha anche suggerito il nome), Lord Kap, Giubbe, Walter, Andres Zanzani, Athlon64®, Willy, Aytin, OoZic, HoHoHo, Nadine, Groucho, Talen e forse altri che ho dimenticato.

Footnotes:

1quelli identificabili nella struttura dall'identificatore "idx1". Nell'ambito degli AVI OpenDML, tali indici si chiamano "legacy indexes".
2in realtà, non è detto che un frame sia esattamente un fotogramma, ma per i nostri scopi possiamo considerare i due termini come equivalenti.
3Mi è stato segnalato che i modelli più recenti leggono anche la GMC con 3 warping points, quindi anche quelli generati da XviD.
4ad esempio, il Panasonic S295.
5una tale oscillazione è rilevabile mediante l'analisi effettuata dal programma DRF Analyzer, dando luogo a una deviazione standard dalla media non prossima a 0.
6Una combinazione lineare è una somma pesata o media pesata, se si ha più familiarità con questi ultimi termini.
7Per "commento" intendo una parte di testo racchiusa tra parentesi quadre, tutta compresa all'interno della stessa entry (eventualmente su più righe).
8Per quest'altro scopo dovrò scrivere una nuova operazione...


File translated from TEX by TTH, version 3.77.
On 13 Nov 2007, 17:59.