¿Por qué la conversión de WMV a MP4 es tan lenta?

12

Estoy tratando de convertir un video de WMV a MP4 con FFmpeg, pero lleva un par de horas. Si trato de convertirlo a AVI, solo me llevará unos 10-15 minutos.

versión ffmpeg

ffmpeg version N-43206-gf857465
built on Aug  4 2012 16:10:39 with gcc 4.7.1 (GCC)

Conversión a MP4

ffmpeg -i input.wmv -vcodec libx264 output.mp4

libavutil      51. 66.100 / 51. 66.100
  libavcodec     54. 49.100 / 54. 49.100
  libavformat    54. 22.100 / 54. 22.100
  libavdevice    54.  2.100 / 54.  2.100
  libavfilter     3.  5.102 /  3.  5.102
  libswscale      2.  1.100 /  2.  1.100
  libswresample   0. 15.100 /  0. 15.100
  libpostproc    52.  0.100 / 52.  0.100
Input #0, asf, from 'input.wmv':
  Metadata:
    WMFSDKVersion   : 12.0.7601.17514
    WMFSDKNeeded    : 0.0.0.0000
    IsVBR           : 0
    encoder         : Lavf54.22.100
  Duration: 01:14:23.06, start: 0.000000, bitrate: 324 kb/s
    Stream #0:0: Video: msmpeg4 (MP43 / 0x3334504D), yuv420p, 1280x720, 15 tbr,
1k tbn, 1k tbc
[libx264 @ 03427620] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle Cac
he64
[libx264 @ 03427620] profile High, level 3.1
[libx264 @ 03427620] 264 - core 125 r2208 d9d2288 - H.264/MPEG-4 AVC codec - Cop
yleft 2003-2012 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deb
lock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 m
e_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chro
ma_qp_offset=-2 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 i
nterlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1
b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=15 scenec
ut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=
0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'output.mp4':
  Metadata:
    WMFSDKVersion   : 12.0.7601.17514
    WMFSDKNeeded    : 0.0.0.0000
    IsVBR           : 0
    encoder         : Lavf54.22.100
    Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1280x720, q=-1--
1, 15 tbn, 15 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (msmpeg4 -> libx264)

Conversión a MP4 con copy

ffmpeg -i input.wmv -c:v:1 copy output.mp4

  libavutil      51. 66.100 / 51. 66.100
  libavcodec     54. 49.100 / 54. 49.100
  libavformat    54. 22.100 / 54. 22.100
  libavdevice    54.  2.100 / 54.  2.100
  libavfilter     3.  5.102 /  3.  5.102
  libswscale      2.  1.100 /  2.  1.100
  libswresample   0. 15.100 /  0. 15.100
  libpostproc    52.  0.100 / 52.  0.100
Input #0, asf, from 'input.wmv':
  Metadata:
    WMFSDKVersion   : 12.0.7601.17514
    WMFSDKNeeded    : 0.0.0.0000
    IsVBR           : 0
    encoder         : Lavf54.22.100
  Duration: 01:14:23.06, start: 0.000000, bitrate: 324 kb/s
    Stream #0:0: Video: msmpeg4 (MP43 / 0x3334504D), yuv420p, 1280x720, 15 tbr,
1k tbn, 1k tbc
[libx264 @ 03437620] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle Cac
he64
[libx264 @ 03437620] profile High, level 3.1
[libx264 @ 03437620] 264 - core 125 r2208 d9d2288 - H.264/MPEG-4 AVC codec - Cop
yleft 2003-2012 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deb
lock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 m
e_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chro
ma_qp_offset=-2 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 i
nterlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1
b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=15 scenec
ut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=
0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'output.mp4':
  Metadata:
    WMFSDKVersion   : 12.0.7601.17514
    WMFSDKNeeded    : 0.0.0.0000
    IsVBR           : 0
    encoder         : Lavf54.22.100
    Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1280x720, q=-1--
1, 15 tbn, 15 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (msmpeg4 -> libx264)

Conversión a AVI con copy

ffmpeg -i input.wmv -c:v:1 copy output.avi

Input #0, asf, from 'input.wmv':
  Metadata:
    WMFSDKVersion   : 12.0.7601.17514
    WMFSDKNeeded    : 0.0.0.0000
    IsVBR           : 0
    encoder         : Lavf54.22.100
  Duration: 01:14:23.06, start: 0.000000, bitrate: 324 kb/s
    Stream #0:0: Video: msmpeg4 (MP43 / 0x3334504D), yuv420p, 1280x720, 15 tbr,
1k tbn, 1k tbc
Output #0, avi, to 'output.avi':
  Metadata:
    WMFSDKVersion   : 12.0.7601.17514
    WMFSDKNeeded    : 0.0.0.0000
    IsVBR           : 0
    ISFT            : Lavf54.22.100
    Stream #0:0: Video: mpeg4 (FMP4 / 0x34504D46), yuv420p, 1280x720, q=2-31, 20
0 kb/s, 15 tbn, 15 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (msmpeg4 -> mpeg4)

¿Hay algunos parámetros adicionales que necesito pasar?

Giorgi
fuente
Por supuesto, es más rápido si solo está copiando el flujo de bits; con copy, no está volviendo a codificar nada. ¿Qué hardware tienes, por ejemplo, CPU? ¿Cuál es su sistema operativo y qué versión de FFmpeg es esa?
slhck
@slhck: La computadora no es muy rápida E5400 2.7GHz pero ¿por qué es lenta para mp4 mientras es rápida para avi?
Giorgi
No veo ninguna salida de AVI en su pregunta. ¿Podría actualizarlo con la salida completa?
slhck
@slhck: salida avi agregada
Giorgi

Respuestas:

17

Copia de flujo

Cuando llame -c:v:1 copy, FFmpeg tomará el flujo de bits de video existente y lo copiará . El flujo de bits de video se encapsula en el contenedor externo, por ejemplo, WMV, AVI o MP4: su flujo de bits de video real es msmpeg4y seguirá siendo así.

Si desea saber más acerca de lo que estoy hablando, vea aquí: ¿Qué es un códec (por ejemplo, DivX?) Y en qué se diferencia de un formato de archivo (por ejemplo, MPG)?

Al copiar el flujo de bits, FFmpeg no necesita decodificar y volver a codificar el video real. Solo necesita fusionar el flujo de bits de video en un nuevo formato contenedor, que a menudo es una operación bastante simple y, por lo tanto, no toma mucho tiempo.

Codificación

En contraste con eso, si llama -vcodec libx264(o -c:v libx264la sintaxis que debe usar porque vcodecestá en desuso), FFmpeg se verá obligado a decodificar el flujo de bits de video desde msmpeg4un formato sin formato, luego lo canalizará en x264un codificador H.264.

x264 es rápido, pero aún así, la codificación de video lleva tiempo, especialmente cuando se trata de contenido de 720p. Y puede llevar más de una hora, especialmente si su entrada ya es más de una hora. Además, su CPU podría no ser la más rápida. Esta es la razón principal por la que los codificadores visuales MPEG-4 más antiguos, como XviD, siguen existiendo y son muy populares: tardan menos tiempo en codificar que los códecs H.264. Es posible que no le brinden el mejor rendimiento en términos de calidad frente al tamaño del archivo, pero son rápidos.

Dicho todo esto: puede acelerar la codificación x264 forzando un preajuste. Los ajustes preestablecidos son configuraciones de optimización del codificador y van desde: ultrarrápido, superrápido, muy rápido, más rápido, rápido, medio, lento, más lento, muy lento. Su comando podría verse así:

ffmpeg -i input.wmv -c:v libx264 -preset fast out.mp4

Debería ejecutarse más rápido que sin el preajuste. El único inconveniente es que no alcanza una calidad tan buena para las mismas tasas de compresión en comparación con, por ejemplo -preset veryslow,.

Aparte de eso, no hay mucho que pueda hacer, excepto invertir en una CPU rápida y asegurarse de que está ejecutando una compilación reciente de FFmpeg con soporte x264.

Para obtener más información, consulte FFmpeg Wiki: Guía de codificación H.264 .

slhck
fuente
Gracias por la respuesta. No estoy seguro de si estaba claro o no, pero si uso la copia, todavía es muy lento. Intenté su comando y se procesó solo 4 segundos después de 5 minutos. Mi video dura aproximadamente 75 minutos y la conversión a avi lleva solo 15 minutos, pero mp4 tarda varias horas.
Giorgi
Entonces, ¿cuál es el mejor para la codificación, libx264 o h264?
Yohanes AI
@NPE No hay diferencia, ya que ffmpeg usa de forma predeterminada libx264cuando especifica 'h264' como codificador.
slhck
1
@PeterCordes lo cambié a fast. Algunas estadísticas interesantes (si se puede confiar en VMAF aquí): streaminglearningcenter.com/blogs/…
slhck
1
@ PeterCordes Hay algunas optimizaciones RC que VMAF no maneja bien, como AQ: github.com/Netflix/vmaf/issues/21 . Estoy de acuerdo con la parte de alta calidad 1080p vs. UHD horrible. El autor del blog está muy abierto a sugerencias sobre cómo mejorar sus pruebas; Ya comenté sobre una mala configuración para x265 hace un tiempo.
slhck
3

Mientras jugaba (horas interminables) con la conversión WMV-> MP4, encontré una forma súper rápida de hacerlo. Pero tiene un precio: un precio de almacenamiento. Si convierte WMV a sin pérdida, entonces de sin pérdida a MP4, realiza la conversión completa en muy poco tiempo. Pero necesita 100 veces más espacio en el disco duro para almacenar la versión sin pérdidas, lo cual es doloroso.

Por lo tanto, puede elegir entre versiones muy lentas o muy intensivas en HDD de conversión WMV-> MP4 y no tiene otra opción.

Convertir un WMV a AVI sin pérdidas: ffmpeg.exe -i screen.wmv -vcodec ffv1 screen.avi Luego convertir AVI sin pérdidas a MP4 (o WebM, no importa) ffmpeg.exe -i screen.avi screen.mp4

¡Súper rápido!

Marcell Foti
fuente