2011-11-03 12 views
6

Estoy implementando un decodificador de audio usando ffmpeg. Mientras leo el audio e incluso busco que funcione, no puedo encontrar una manera de limpiar los buffers después de buscar, así que no tengo artefactos cuando la aplicación comienza a leer el audio inmediatamente después de buscar.FFMPEG Buscando trae artefactos de audio

avcodec_flush_buffers no parece tener ningún efecto en los búfers internos. Este problema ocurre con todos los decodificadores (mp3, aac, wma, ...) pero con PCM/WAV (que no usa los búfers internos para guardar los datos para decodificar ya que el audio no está comprimido).

El fragmento de código es simple:

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

Explicando:

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

¿Alguna idea sobre lo que debe hacer para que pueda buscar y obtener sin audio residual? Gracias!

+0

¿No hay ideas? Estoy tratando de arreglar esto por casi 2 semanas sin ninguna idea sobre lo que puede estar causando esto ... ¿debería funcionar como está? –

+0

El mensaje también se envió a la lista de correo oficial de ffmpeg-usuario. Ayuda aún necesitada –

+0

¿Puedes describir los artefactos con más detalle? ¿Son clics y pops? –

Respuesta

3

Nunca he escrito un reproductor de audio con capacidad de búsqueda, pero sospecho que está sucediendo esto. Cada paquete de audio se decodifica en un fragmento de la onda de sonido original. Normalmente, estos fragmentos se unen secuencialmente entre sí y el resultado es una onda continua, que se escucha como audio sin artefactos. Cuando busca, fuerza a dos fragmentos de partes dispares del archivo a toparse unos con otros. Esto generalmente introduce una discontinuidad en la onda de sonido resultante, que el oído percibe como un clic o pop, o como usted lo llama (supongo) un artefacto.

Aquí hay un ejemplo más concreto. Supongamos que ha jugado los primeros 25 paquetes de audio antes de buscar. Digamos que el paquete 25 se decodifica en una onda cuya última muestra es 12345. Mientras se está procesando el paquete 25, busca el paquete 66. Digamos que la primera muestra del paquete 66 es -23456. Por lo tanto, la secuencia de audio digital salta de 12345 a -23456 a través de la búsqueda. Esta es una gran discontinuidad, y se escuchará como un pop.

Creo que una solución es tomar un paquete adicional antes de comenzar a buscar (paquete 26 en mi ejemplo), decodificarlo en un buffer fuera de línea, aplicar un fade-out, y luego ponerlo en la cola de reproducción. Después de buscar la ubicación deseada, tome el primer paquete (66 en mi ejemplo), decodifíquelo en otro buffer fuera de línea, aplique un fade-in y luego colóquelo en la cola de reproducción. Esto debería garantizar ondas de sonido suaves y búsqueda libre de artefactos.

Si es inteligente, puede hacer que el fundido de salida y el fundido de entrada sean lo más cortos o largos que desee. Creo que solo unos pocos milisegundos deberían ser suficientes para evitar artefactos. Incluso podría aplicar un fundido cruzado de los paquetes antiguo y nuevo. También podría ser suficiente simplemente anotar el último valor de muestra en el último paquete antes de la búsqueda, y gradualmente reducirlo a cero en unas pocas muestras, en lugar de tirarlo a cero inmediatamente. Esto podría ser más fácil que decodificar un paquete adicional.

Esta es mi suposición acerca de cómo se podría abordar este problema. Esto es claramente un problema resuelto, por lo que te animo a que también mires los reproductores de audio de código abierto y veas cómo implementan la búsqueda. Programas como Audacity, Totem, Banshee, RhythmBox, Amarok o VLC o frameworks como GStreamer pueden ser buenos ejemplos de los que aprender. Si encuentra que emplean técnicas notables, informe el tema aquí. Creo que las personas querrán saber cuáles son. ¡Buena suerte!

3

Es un error en ffmpeg. Los búferes internos no se descargan y, por lo tanto, cuando va a obtener un paquete/marco después de enjuagar, obtiene los datos de búsqueda previa. Parece que se corrigió a partir del 3-16-12, por lo que podría incorporar esta solución usted mismo o actualizar ffmpeg.

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

Como una actualización, el error anterior es realmente un problema, pero hay un segundo error con AAC específicamente.

Desde hace cinco meses, otro usuario encontró este error y se informó que se corrigió. https://ffmpeg.org/trac/ffmpeg/ticket/420

La corrección era una función de descarga que se agrega aaacdec.c que borra sus búferes internos. El problema es que hay dos decodificadores definidos en aacdec.c, y solo uno recibió el puntero de función de descarga. Si usa el otro decodificador (más común), aún no se borrará correctamente.

Si está en condiciones de construir ffmpeg mismo, la solución es añadir .flush = ras, a la parte inferior de la definición de avcodec ff_aac_decoder (que está en la parte inferior del archivo.)

Dejaré que los chicos de ffmpeg sepan, así que espero que se pueda incluir en la rama principal.

+0

Choque así que el cartel original con suerte ve esto – JHawkZZ

+0

¡Muchas gracias! Lo recompilaré y dejaré mi camino alternativo ... que es feo pero funciona ... –

Cuestiones relacionadas