Reparar correctamente vídeos codificados con una versión antigua de x264

Reparar correctamente vídeos codificados con una versión antigua de x264

Debido a un error en versiones antiguas de x264, transmisiones de video h.264 con las siguientes tres propiedades:

  1. codificado con x264 build 150 o anterior
  2. usando submuestreo de croma 4:4:4
  3. bitstream no contiene información de la versión x264

muchos reproductores de vídeo no reproducirán correctamente. Las nuevas versiones del reproductor de vídeo mpvtienen una opción dedicada

--vd-lavc-assume-old-x264

abordando específicamente este tema (ver:https://mpv.io/manual/master/).

Sobre elRastreador de errores de FFmpegSe sugiere agregar el SEI.h264 adecuado a la transmisión de video (que contiene la información de la versión x264, supongo). Prefiero no confiar en esos trucos, así que mi pregunta es:¿Existe una forma "adecuada" (idealmente usando ffmpeg) de reparar los archivos como si hubieran sido codificados con una nueva versión (reparada) de x264 en primer lugar??

Obviamente me gustaría seguir siendo (más o menos) vídeocalidadytamaño del archivo. Si es necesario volver a codificar, no debería cambiar nada más que corregir el comportamiento defectuoso de la antigua implementación x264. (Informacion adicional:El informe de errorda un ejemplo de archivo corrupto. Se conjetura que el error en el antiguo x264 probablemente fueintroducido aquí.)

Respuesta1

Gracias por publicar esta pregunta, también me ayudó a comprender la naturaleza del problema que estaba teniendo. Tengo una solución que parece funcionar.

En mi caso estoy usando ffmpeg de los repositorios de Ubuntu. La última versión que pudo decodificar mis archivos libx264 fue la 2.8.6. Después de actualizar a 2.8.14 o 2.8.15, tuve los problemas de decodificación que usted describe. No quiero volver a codificar mis videos antiguos, solo quiero arreglar el encabezado para que ffmpeg pueda identificar correctamente el error que se introdujo durante la codificación original y reproducirlos correctamente.

Así que primero que nadadescargué el binario estático que incluye la versión más reciente de ffmpeg, v4. Vinculé este binario ffmpeg4en mi sistema para poder controlar qué versión estoy usando. Necesitamos algunas de las nuevas funciones que se introdujeron después de la versión 2.8 (no estoy seguro de cuándo). Si ya tiene instalada una versión más nueva de ffmpeg, simplemente úsela y reemplácela ffmpeg4con ffmpeglos siguientes comandos.

Ahora, extraiga el flujo de bits sin procesar de su video roto (llámelo ROTO.mkv).

ffmpeg4 -i BROKEN.mkv -vcodec copy -an -bsf:v h264_mp4toannexb raw.h264

No estoy seguro de que el indicador h264_mp4toannexb sea necesario,puede ser autoinsertadopara este formato.

Ahora, coloque el flujo de bits en un nuevo contenedor mp4,y corrija la información sobre la antigua compilación x264 con errores en el encabezado SEI.

ffmpeg4 -r 30 -i raw.h264 -avoid_negative_ts 1 -bsf:v h264_metadata='sei_user_data=dc45e9bde6d948b7962cd820d923eeef+x264 - core 150' -c copy FIXED.mp4

El flujo de bits no contiene información de marca de tiempo, por lo que recibirás un montón de advertencias aquí. También descubrí que tenía que configurar manualmente la velocidad de fotogramas en 30 fps ( -r 30) porque de lo contrario adivinaba una velocidad de fotogramas variable entre 25 y 30 fps. No sé cómo extraer correctamente las marcas de tiempo o mezclarlas correctamente en el nuevo contenedor. ¡Avíseme si tiene una solución! Mucha gente lo recomienda -fflags +genptspero esto noparece hacer cualquier cosapara mí. Finalmente, agregué -avoid_negative_ts 1para que la marca de tiempo del primer cuadro no sea negativa.

Finalmente, y esto es opcional, si deseas poner los resultados en un contenedor MKV puedes hacer esto

ffmpeg4 -i FIXED.mp4 -c copy FIXED.mkv

Por quéconvertir primero a MP4 y luego a MKV? Parece que el contenedor MKV simplemente se negará a continuar sin marcas de tiempo, pero MP4 lo hará y solo emitirá advertencias. Luego podrás convertir a MKV sin advertencias.

Entonces, después de todo esto, tengo archivos MP4 y MKV en funcionamiento. Sin embargo, inspeccioné algunos fotogramas y hay cambios menores (cambios de luminancia del orden de ~2 niveles). No entiendo por qué sucedió esto porque no debería haber habido pérdidas. Por favor, avíseme si tiene sugerencias sobre cómo se puede hacer esto mejor.

Editar: noté que algunas de mis marcas de tiempo eran negativas en el contenedor MP4, comenzando en -0.066667s. Después de pasar a un contenedor MKV, todas las marcas de tiempo negativas se convirtieron en ceros. Agregar -output_ts_offset 0.066667al comando solucionó este problema y los hizo comenzar en cero. Sin embargo, no entiendo por qué comenzó en -0,066667.

Edición 2: una mejor manera de eliminar marcas de tiempo negativas es usar "-avoid_negative_ts 1" al codificar el mp4.

información relacionada