Dlaczego konwersja WMV do MP4 jest tak wolna?

12

Próbuję przekonwertować wideo z WMV do MP4 za pomocą FFmpeg, ale zajmuje to kilka godzin. Jeśli spróbuję przekonwertować go na AVI, zajmie to tylko około 10-15 minut.

wersja ffmpeg

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

Konwersja do 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)

Konwersja do MP4 za pomocą 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)

Konwersja do AVI za pomocą 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)

Czy są jakieś dodatkowe parametry, które muszę przekazać?

Giorgi
źródło
Oczywiście jest to szybsze, jeśli kopiujesz strumień bitów - dzięki copynie będziesz niczego przekodowywać. Jaki masz sprzęt, np. Procesor? Jaki jest twój system operacyjny i która to wersja FFmpeg?
slhck,
@slhck: Komputer nie jest bardzo szybki E5400 2,7 GHz, ale dlaczego jest wolny dla mp4, podczas gdy jest szybki dla avi?
Giorgi,
Nie widzę żadnych danych wyjściowych AVI w twoim pytaniu. Czy możesz zaktualizować go z pełną wydajnością?
slhck,
@slhck: dodano wyjście avi
Giorgi,

Odpowiedzi:

17

Kopiowanie strumieniowe

Gdy zadzwonisz -c:v:1 copy, FFmpeg weźmie istniejący strumień bitów wideo i skopiuje go strumieniowo . Strumień wideo jest właśnie zamknięty w zewnętrznym kontenerze, np. WMV, AVI lub MP4 - rzeczywisty strumień bitów wideo jest msmpeg4i pozostanie taki.

Jeśli chcesz dowiedzieć się więcej o tym, o czym mówię, zobacz tutaj: Co to jest kodek (np. DivX?) I czym różni się od formatu pliku (np. MPG)?

Podczas kopiowania strumienia bitów FFmpeg nie musi faktycznie dekodować i ponownie kodować rzeczywistego wideo. Musi tylko połączyć strumień bitów wideo w nowy format kontenera, co często jest dość prostą operacją i dlatego nie zajmuje dużo czasu.

Kodowanie

W przeciwieństwie do tego, jeśli wywołasz -vcodec libx264(lub -c:v libx264składnię, której powinieneś użyć, ponieważ vcodecjest przestarzała), FFmpeg będzie zmuszony zdekodować strumień bitów wideo z msmpeg4formatu surowego, a następnie potokować go do x264kodera H.264.

x264 jest szybki, ale nadal kodowanie wideo zajmuje dużo czasu - szczególnie gdy jest to zawartość 720p. Może to potrwać dłużej niż godzinę, szczególnie jeśli Twój wkład jest już dłuższy niż jedna godzina. Ponadto procesor może nie być najszybszy. Jest to główny powód, dla którego starsze kodery wizualne MPEG-4, takie jak XviD, są nadal popularne i bardzo popularne: kodowanie zajmuje mniej czasu niż kodeków H.264. Mogą nie zapewniać najlepszej wydajności pod względem jakości w porównaniu do rozmiaru pliku, ale są szybkie.

To wszystko powiedziane: można przyspieszyć kodowanie x264, wymuszając ustawienie wstępne. Ustawienia wstępne to ustawienia optymalizacji enkodera i zakres od: ultraszybki, superszybki, bardzo szybki, szybszy, szybki, średni, wolny, wolniejszy, bardzo wolny. Twoje polecenie może wyglądać następująco:

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

Powinien działać szybciej niż bez ustawienia wstępnego. Jedyną wadą jest to, że nie osiąga tak dobrej jakości dla tych samych współczynników kompresji w porównaniu na przykład z -preset veryslow.

Poza tym niewiele możesz zrobić, oprócz inwestowania w szybki procesor i upewnienia się, że korzystasz z najnowszej wersji FFmpeg z obsługą x264.

Aby uzyskać więcej informacji, zobacz FFmpeg Wiki: Podręcznik kodowania H.264 .

slhck
źródło
Dziękuję za odpowiedź. Nie jestem pewien, czy byłem czysty, czy nie, ale jeśli używam kopiowania, nadal jest to bardzo powolne. Wypróbowałem twoje polecenie i przetworzyło to tylko 4 sekundy po 5 minutach. Mój film ma około 75 minut, a konwersja do avi zajmuje tylko 15 minut, ale mp4 zajmuje kilka godzin.
Giorgi,
więc który z nich jest najlepszy do kodowania, libx264 lub h264?
Yohanes AI,
@NPE Nie ma różnicy, ponieważ ffmpeg domyślnie używa, libx264gdy jako koder podasz „h264”.
slhck
1
@PeterCordes Zmieniłem to na fast. Kilka interesujących statystyk (jeśli można zaufać VMAF tutaj): streaminglearningcenter.com/blogs/…
slhck
1
@PeterCordes Istnieje kilka optymalizacji RC, których VMAF nie radzi sobie dobrze, takich jak AQ: github.com/Netflix/vmaf/issues/21 . Zgadzam się z wysokiej jakości 1080p kontra gówniana część UHD. Autor bloga jest bardzo otwarty na sugestie, jak poprawić swoje testy; Już jakiś czas temu skomentowałem błędną konfigurację x265.
slhck
3

Kiedy grałem (niekończące się godziny) z konwersją WMV-> MP4, znalazłem superszybki sposób na zrobienie tego. Ale ma cenę: cenę przechowywania. Jeśli przekonwertujesz WMV na bezstratny, a następnie z bezstratnego na MP4, nastąpi pełna konwersja w krótkim czasie. Ale potrzebujesz 100 razy więcej miejsca na dysku twardym, aby przechowywać bezstratną wersję, co jest bolesne.

Okazuje się, że możesz wybrać wersję bardzo wolną lub bardzo intensywną HDD konwersji WMV-> MP4 i nie masz innego wyboru.

Konwersja WMV do bezstratnego AVI: ffmpeg.exe -i screen.wmv -vcodec ffv1 screen.avi Następnie konwersja bezstratnego AVI do MP4 (lub WebM, to nie ma znaczenia) ffmpeg.exe -i screen.avi screen.mp4

Super szybko!

Marcell Foti
źródło