2011-11-03 14 views
6

Sto implementando un decodificatore audio usando ffmpeg. Durante la lettura di audio e persino la ricerca di opere già, non riesco a capire un modo per cancellare i buffer dopo aver cercato in modo da non avere artefatti quando l'app inizia a leggere l'audio subito dopo la ricerca.FFMPEG Seeking porta artefatti audio

avcodec_flush_buffers non sembra avere alcun effetto sui buffer interni. Questo problema si verifica con tutti i decodificatori (mp3, aac, wma, ...) ma PCM/WAV (che non utilizza i buffer interni per contenere i dati da decodificare poiché l'audio non è compresso).

Il frammento di codice è semplice:

av_seek_frame(audioFilePack->avContext, audioFilePack->stream, posInTimeFrame, AVSEEK_FLAG_ANY); 
avcodec_flush_buffers(audioFilePack->avContext->streams[audioFilePack->stream]->codec); 

Spiegando:

audioFilePack->avContext = FormatContext 
audioFilePack->stream = Stream Position (also used to read audio packets) 
audioFilePack->avContext->streams[audioFilePack->stream]->codec = CodecContext for the codec used 

Tutte le idee su quello che devo fare in modo che possa cercare e ottenere senza audio residuo? Grazie!

+0

Per favore, nessuna idea? Sto cercando di risolvere questo problema per quasi 2 settimane senza alcuna idea su cosa potrebbe causare questo ... dovrebbe funzionare così com'è? –

+0

Il messaggio viene anche inviato alla mailing list ufficiale di ffmpeg-user. Aiuto ancora necessario. –

+0

Puoi descrivere gli artefatti in modo più dettagliato? Sono click e pop? –

risposta

3

Non ho mai scritto un lettore audio con funzionalità di ricerca, ma ciò che sospetto sta succedendo è questo. Ogni pacchetto audio decodifica in uno snippet dell'onda sonora originale. Normalmente, questi frammenti si sovrappongono in sequenza l'un l'altro e il risultato è un'onda continua, che si sente come audio senza artefatti. Quando si cerca, si forza due frammenti di parti diverse del file a conficcarsi l'un l'altro. Questo in genere introduce una discontinuità nell'onda sonora risultante, che l'orecchio percepisce come un clic o un pop, o come lo chiamate (immagino) un artefatto.

Ecco un esempio più concreto. Supponiamo che tu abbia suonato i primi 25 pacchetti di audio prima di cercare. Diciamo che il pacchetto 25 decodifica in un'onda il cui ultimo campione è 12345. Mentre il pacchetto 25 viene reso all'altoparlante, si cerca il pacchetto 66. Diciamo che il primo campione del pacchetto 66 è -23456. Pertanto, il flusso audio digitale passa da 12345 a -23456 attraverso la ricerca. Questa è un'enorme discontinuità e sarà ascoltata come un pop.

Penso che una soluzione sia quella di prendere un pacchetto extra prima di iniziare a cercare (pacchetto 26 nel mio esempio), decodificarlo sul buffer offline, applicare una dissolvenza in uscita e quindi metterlo nella coda di riproduzione. Dopo aver cercato la posizione desiderata, prendi il primo pacchetto (66 in mio eaxmple), decodificalo su un altro buffer offline, applica una dissolvenza in apertura e inseriscila nella coda di riproduzione. Questo dovrebbe garantire onde sonore lisce e ricerca senza artefatti.

Se sei intelligente, puoi rendere la dissolvenza in chiusura e in chiusura il più breve o lungo che desideri. Penso che solo pochi millisecondi dovrebbero essere sufficienti per evitare artefatti. Potresti anche applicare una dissolvenza incrociata dai pacchetti vecchi e nuovi. Potrebbe anche essere sufficiente prendere semplicemente nota dell'ultimo valore di campionamento nell'ultimo pacchetto prima della ricerca e gradualmente portarlo a zero su alcuni campioni, piuttosto che portarlo a zero immediatamente. Questo potrebbe essere più semplice della decodifica di un pacchetto extra.

Questa è la mia ipotesi su come questo problema potrebbe essere risolto. Questo è chiaramente un problema risolto, quindi ti invito a guardare anche i lettori audio open-source e vedere come implementano la ricerca. Programmi come Audacity, Totem, Banshee, RhythmBox, Amarok o VLC o framework come GStreamer potrebbero essere dei buoni esempi da cui imparare. Se trovi che impiegano tecniche degne di nota, ti preghiamo di riferire sul tema qui. Penso che le persone vorranno imparare quello che sono. In bocca al lupo!

3

È un bug in ffmpeg. I buffer interni non vengono scaricati, e quindi quando si va a prendere un pacchetto/frame dopo lo svuotamento, si ottengono i dati pre-ricerca. Sembra risolto dal 3-16 al 12, quindi potresti incorporare questa correzione da te o aggiornare ffmpeg.

http://permalink.gmane.org/gmane.comp.video.libav.devel/23455

come aggiornamento, l'errore sopra è effettivamente un problema, ma c'è una seconda insetto con AAC specificamente.

A partire da cinque mesi fa, un altro utente ha rilevato questo errore ed è stato segnalato che è stato risolto. https://ffmpeg.org/trac/ffmpeg/ticket/420

La correzione era una funzione di svuotamento aggiunta a aacdec.c che cancella i suoi buffer interni. Il problema è che ci sono due decodificatori definiti in aacdec.c, e solo a uno è stato dato il puntatore della funzione di scarico. Se si utilizza l'altro decodificatore (più comune), non verrà ancora cancellato correttamente.

Se siete in grado di costruire da soli ffmpeg, la correzione è quello di aggiungere .flush = filo, al fondo della definizione di AVCodec ff_aac_decoder (che si trova alla fine del file.)

Lascerò che i ragazzi di ffmpeg lo sappiano, quindi spero che possano essere inclusi nel ramo principale.

+0

Bumping così il poster originale spera che questo lo veda – JHawkZZ

+0

Grazie mille! Lo ricompenserò e abbandonerò il mio modo alternativo ... che è brutto ma funziona ... –

Problemi correlati