STM32vldiscovery Video Player

Nell' applicazione che propongo vedremo come la STM32vldiscovery board con la sola aggiunta di un display TFT ed un socket per SD-Card, riesca a decodificare e riprodurre video con risoluzione di 160*120 pixel a 16 fps con audio a 22kHz.

Si trovano in rete numerosi esempi di player video che utilizzano un microcontrollore, un display TFT, una SD card o altri dispositivi di memorizzazione. La maggior parte di questi si limita però ad un puro trasferimento di una sequenza di immagini bitmap dal dispositivo di memorizzazione al display.

Questo metodo è poco efficiente in termini di spazio utilizzato per la memorizzazione dei file, ma allo stesso tempo è difficile pensare di utilizzare uno dei comuni formati di compressione video ed affidare la decodifica ad una mcu di fascia media.

Esistono però sul mercato lettori MP3 economici dotati di un piccolo display TFT, che consentono di riprodurre video di discreta qualità utilizzando file compressi nel formato AMV, formato derivato dal Motion JPEG.

Il costo contenuto di questi dispositivi ha favorito la diffusione sia del formato video AMV che del software necessario alla codifica, la maggior parte di questo gratuito e di pubblico dominio.

Il formato AMV
I file AMV sono fomati da una Header che specifica i parametri globali del video (dimensione fotogrammi, framerate, audio samplerate, dimensione del file etc.), seguita dalla sequenza di fotogrammi codificati in JPEG alternati a segmenti della traccia audio in formato ADPCM.

Poichè il video è composto da singole immagini indipendenti, rispetto ai comuni sistemi di codifica il decoder non ha necessità di utilizzare un buffer per memorizzare key-frame a cui fare riferimento. Questo riduce notevolmente la quantità di RAM necessaria alla decodifica.

Inoltre a differenza di un file JPEG standard in cui oltre al segmento che rappresenta l' immagine vera e propria sono presenti una serie di parametri e tabelle utilizzati nel processo di decodifica, i fotogrammi dei file AMV sono codificati utilizzando sempre un unico set di parametri e tabelle. Questo contribuisce a ridurre ulteriormente le dimensioni del file e consente di strutturare un decoder JPEG dedicato più efficiente rispetto ad uno generico.

La traccia audio è suddivisa in segmenti la cui durata è funzione del framerate. Nel nostro caso (16 fps) ogni segmento dell' audio dura circa 62 mSec. La codifica ADPCM utilizza 4 bit per sample e quindi il rapporto di compressione che si ottiene è fisso, in caso di audio a 16 bit è pari a 4/1.

La qualità del segnale decompresso è abbastanza buona per la banda vocale mentre sui segnali musicali si nota una riduzione di dinamica e fedeltà di riproduzione.Il processo di decodifica è abbastanza semplice e richiede poche risorse per essere eseguito. Una implementatazione del codec ADPCM su STM32 è descritta nella AN2931 della ST.

Il software
L' applicazione consiste principalmente in tre moduli: il decoder JPEG dedicato, il decoder ADPCM, il modulo per la gestione della SD-Card.

Il decoder JPEG è il modulo principale dell' applicazione. Per ottenere le prestazioni necessarie per la riproduzione di 16 fps il modulo è scritto interamente in assembly e ottimizzato per l' architettura CortexM3. Utilizza un buffer circolare su cui caricare preventivamente i dati e decodifica 4 blocchi di crominanza (Y) e 2 blocchi di luminanza (Cr, Cb) in un singolo passo. I dati in output dal decoder, equivalenti ad un blocco di 16X16 pixel, vengono traslati da YCrCb in RGB/565 ed inviati al display. Il processo viene ripetuto sequenzialmente fino al completamento dell' immagine che costituisce il fotogramma.

Il decoder ADPCM è integrato nell' IRQ_Handler del Timer2, è anche questo scritto in assembly ed utilizza un buffer di input abbastanza ampio per ottenere una riproduzione senza gap al prezzo di una piccola latenza. Il Timer 2 viene inizializzato in modo da generare un irq alla stessa frequenza dell' audio (22kHz). La decodifica avviene a fasi alterne: ogni irq pari, prelevato un byte dal buffer e decodificati i 2 sample corrispondenti, il primo viene immediatamente inviato al DAC ed il secondo viene memorizzato per essere utilizzato dal ciclo irq successivo.

La lettura della SD-Card viene effettuata tramite la SPI2 e utilizza il DMA per il trasferimento in memoria dei settori del file in riproduzione in modo da alleggerire il carico per la CPU. Il decoder JPEG utilizza direttamente il buffer utilizzato per la lettura del file mentre i dati audio vengono via via accodati nel buffer dedicato.

Una 'mini' interfaccia utente
Completa l'applicazione una piccola interfaccia utente per la selezione del file da riprodurre tra quelli presenti nella SD-Card. Ad ogni reset viene testata la presenza della SD-Card che deve essere formattata in FAT16 o FAT32 e vengono lette dalla root-dir fino a 32 entry dei file con estensione AMV. Vengono quindi elencati i nomi dei file (primi 8 caratteri) e la dimensione approssimativa in Mb in gruppi di 5 per pagina.

Mediante il pulsante P1 si può scorrere l'elenco dei file e spostarsi tra le pagine dell' elenco. Una breve pressione del pulsante (< 0.5 Sec) farà spostare la selezione sulla riga successiva, una pressione prolungata ( >0.5 Sec) avvierà la riproduzione del file selezionato o effettuerà il cambio pagina.

Il tool di sviluppo
L'applicazione è sviluppata e compilata utilizzando il Keil MDK nella versione dimostativa limitata a 32K scaricabile gratuitamente. La cartella del progetto AMV_dec_18 va copiata nel percorso \....\stm32vldiscovery_package\Projects\example\ Il progetto AMV_dec_18.uv4 è contenuto nella cartella MDK-ARM pronto per essere compilato o modificato secondo le vostre esigenze. Tutto il codice o parte di esso può essere liberamente utilizzato, modificato o ridistribuito sotto i termini della GNU General Public License.

L'Hardware
Il progetto utilizza un display TFT da 1.8 pollici da 160x128 pixel (IC driver TL1771) con interfaccia parallela a 8 bit ed un socket per SD-Card, connessi alla STM32vldiscovery board rispettivamente alla GPIOC e alla SPI2 eseguendo le semplici connessioni illustrate nello schema allegato. L' uscita del DAC1 va connessa tramite un condensatore di disaccoppiamento all'ingresso di un qualsiasi amplificatore audio.

Utilizzare un diverso TFT
Il modulo TFT può essere sostituito con qualsiasi altro dotato sempre di interfaccia parallela a 8bit apportando delle semplici modifiche a due funzioni del file TFT_18.C

1) La funzione TFT_18_Init() e' sufficiente sostituire la sequenza di inizializzazione con quella del display che andrete ad utilizzare, prestando attenzione a configurare il display in modo da avere le coordinate 0,0 nell' angolo superiore sinistro.

2) La funzione TFT_18_set_win(x0,y0,x1,y1) modificare la funzione per impostare i relativi registri del vostro display. Per un display con risoluzione maggiore di 160x128 potete aggiungere alle coordinate un offset per posizionare l'immagine in qualsiasi punto dell'area di visualizzazione.

Non ci dovrebbero essere altre modifiche da apportare perchè la quasi totalità dei controller per display a 8bit utilizza sia lo stesso numero di pin sia lo stesso ciclo di scrittura.

L'Encoder da utilizzare
Per la codifica in formato AMV ho adoperato il tool di pubblico dominio MP3-Player Utility V4.18 che raccomando di utilizzare perchè non so se altre versioni producano un output compatibile con il decoder. L'utilizzo del tool è abbastanza intuitivo: basta aprire uno o più file da convertire nei formati supportati, impostare la risoluzione su 160x120, selezionare l'opzione flip vertical e avviare la conversione.

Una volta terminato, formattare una SD-Card in FAT16 o FAT32, copiare sulla root-dir i file AMV ottenuti e .... buona visione !

Conclusioni
Una applicazione forse insolita per una MCU a 24MHz con 8K di RAM, ma che riesce a evidenziare le potenzialità offerte dal core CortexM3 e che vista la semplicità di realizzazione consiglio di provare a tutti gli utenti della STM32vldiscovery.

Scarica subito una copia gratis
Tags:

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend