Opracowaliśmy aplikację do transkodowania źródłowych plików .mov do formatu .ogg, .mp4 i .webm. Obecnie działa na instancji AWS EC2 g2.8xlarge. Działa (yay!).

Moje pytanie: mimo że przekazuję -threads 0 do polecenia ffmpeg (w rzeczywistości ustawiam ffmpeg.threads w php-ffmpeg ), działający proces jest czasami wykonywany tylko na jednym rdzeniu. Dlaczego to się dzieje? Zobacz poniżej dane wyjściowe polecenia htop:

wyjście htop

Jak widać , Core # 21 jest wyczerpany. Za kilka sekund przejdzie na inny, zamiast maksymalizować je wszystkie, tak jak bym chciał, i znacznie przyspieszyć mój proces kodowania. Sytuacja jest przejściowa; podczas niektórych uruchomień wszystkie procesory osiągnięto maksymalny limit, ale w innych nie są i korzystamy tylko z jednego procesora. Kolega wspomniał, że być może kodek, którego używamy w niektórych formatach, nie obsługuje wykonywania wielowątkowego podczas kodowania, chociaż nie mogę jeszcze sprawdzić, czy to jest zachowanie, które obserwuję.

Czy tak jest? Jeśli tak, jakie kodeki dla powyższych formatów pozwolą nam transkodować do tych formatów docelowych, korzystając z całego naszego dostępnego sprzętu? Domyślne kodeki ustawione dla php-ffmpeg znajdują się poniżej;

 Video Audio Ogg libtheora libvorbis WebM libvpx libvorbis X264 libx264 libfaac 

Aktualizacja

Patrząc na uruchomione procesy, poniżej znajduje się polecenie ffmpeg uruchamiane dla MP4 (obecnie nasycające wszystkie 32 rdzenie):

Tak naprawdę nie buduję tego polecenia bezpośrednio, php-ffmpeg jest, chociaż uważam, że mam przynajmniej niewielką kontrolę nad tym, co się dzieje w nim (na przykład nie mam pojęcia, dlaczego na początku jest wiele wpisów -metadata:s:v:0)

Komentarze

  • W tym wierszu poleceń jest ', poza zduplikowanymi opcjami (-s trzy razy , ostatnia o innym rozmiarze). Jawne ustawienie kilku argumentów na ich bieżące wartości domyślne (np. -i_qfactor, -subq, -qcomp) jest dziwne i może dawać złe wyniki z przyszłym libx264. (Prawdopodobnie nie, ale tylko dlatego, że libx264 jest prawie gotowe i stabilne, nie jest intensywnie rozwijane. Gdyby robił takie rzeczy dla x265, byłoby to złe.) W każdym razie, 2-przebiegowe 1200k jest w porządku, ale możesz preferować docelowe -jakość crf. Nie ' nie określa -preset. 🙁
  • libfaac isn ' t tak dobry jak libfdk_aac . Jeśli ' używasz tego w usłudze płatnej, ' d musisz jednak sprawdzić licencję libfdk_aac. Brakuje również tej linii cmd -movflags +faststart
  • Możliwe jest również, aby ffmpeg generował wiele wyników z tego samego ' Po prostu mam wiele sekwencji opcji-wyjściowych nazwa-pliku-wyjściowego w linii poleceń. Podsumowując, ' nie jestem pod wielkim wrażeniem php-ffmpeg, jeśli to to rodzaj linii cmdline, z jaką się pojawia. Może mógłbyś użyć go inaczej, aby generował wiele wyników naraz, więc nie byłoby ' t być jednowątkowym krokiem teory. W każdym razie, jeśli to zadziała, to świetnie, ale uważaj na zmiany w domyślnych ustawieniach kodera i znaczenie x264 subme poziomów zmieniających się w sposób, który ja Twoja linia cmd szkodzi jakości.
  • @Peter wielkie dzięki. Myślę, że tak naprawdę odpowiedź brzmi: muszę debugować, jak budowany jest ten cmd. Jeśli naprawdę mogę włożyć wiele wyjść do tego polecenia, myślę, że prawdopodobnie dałoby mi to lepsze ujęcie maksymalizacji obciążenia sprzętu
  • trac.ffmpeg .org / wiki / Tworzenie% 20multiple% 20 wyjść . I tak, zgadzam się, że ' jest prawdopodobnie najlepszy. W przeciwnym razie masz zadanie, które ' jest jednowątkowe przez pewien czas i ładuje wszystkie rdzenie przez inny czas. Trudno zaplanować zadania, które zachowują się w ten sposób.

Odpowiedź

Przy okazji, to pytanie może być lepsze w przypadku przepełnienia stosu, a może unix.stackexchange, a może błąd serwera. Wydaje mi się, że ta witryna jest mniej skupiona na pytaniach, które nie obejmują decyzji opartych na wartościach kreatywnych lub przynajmniej percepcyjnej jakości wideo / audio. Jednak ja jestem bardzo zainteresowany szczegółami technicznymi, więc odpowiem.

FFmpeg domyślnie używa wielowątkowości, więc prawdopodobnie nie potrzebujesz -threads 0. Jeśli twoje kodowanie jest wąskie w przypadku jednowątkowego filtru lub dekodera, zobaczysz pełne obciążenie jednego rdzenia i niewielkie obciążenie wielu innych rdzeni.

Jedną z rzeczy, które możesz zrobić, to sprawdzić mediainfo wyjściowego wideo. x264 pozostawia swoje ustawienia w łańcuchu ASCII w nagłówku h.264. Więc albo strings -n20, albo mediainfo, aby uzyskać:

... Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Bits/(Pixel*Frame) : 0.051 Stream size : 455 MiB (89%) Writing library : x264 core 146 r2538+1 d48ec67 Encoding settings : cabac=1 / ref=6 / deblock=1:0:0 / analyse=0x3:0x133 / me=umh / subme=10 / psy=1 / psy_rd=0.70:0.10 / mixed_ref=1 / me_range=24 / chroma_me=1 / trellis=2 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-3 / threads=4 / lookahead_threads=1 / sliced_threads=0 / nr=50 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=5 / b_pyramid=2 / b_adapt=2 / b_bias=0 / direct=3 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=60 / rc=crf / mbtree=1 / crf=22.5 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=3:0.60 Color primaries : BT.709 Transfer characteristics : BT.709 Matrix coefficients : BT.709 

Uwaga „Wątki = 4” tam. Myślę, że ręcznie ustawiłem to na moim czterordzeniowym i5 2500k, zamiast pozwolić x264 używać domyślnych procesorów * 1.5, ponieważ miałem uruchomione filtry obciążające procesor (hqdn3d i lanczos-downscale).

W każdym razie, libx264 z ustawieniem wstępnym takim jak slower nie powinno mieć żadnego problemu z utrzymaniem zajętości wielu rdzeni. Istnieją pewne części kodowania, które są z natury szeregowe (np. Kodowanie CABAC końcowego strumienia bitów), więc wideo o dużej szybkości transmisji bitów, które nie zajmuje dużo czasu na udoskonalanie odniesień do procesora (wysokie subme) do wielu ramek (high ref) może pokazywać wzorzec ładowania podobny do twojego (jeden wątek używa 100% procesora, inne nie).

I „Nie jestem w 100% pewien, czy szybsze presety są mniej równoległe, ale wiem, że CABAC jest szeregowy.

Aby uzyskać masową równoległość, libx264 może użyć dużej ilości pamięci RAM do przechowywania ramek i nadal patrzeć w przód przez 2 lub więcej GOP i koduje je niezależnie. Nie ma jednak opcji, aby działać w ten sposób.

Jednym ze sposobów wykorzystania WIELU rdzeni jest uruchomienie wielu oddzielnych kodowań równolegle, zamiast tylko serii pojedynczego kodowania przy użyciu wszystkich rdzeni. Działa to tylko wtedy, gdy masz wiele plików wejściowych, które chcesz osobno zakodować. Zamiast narzutu na wątki zamiast większej pojemności pamięci i przepustowości (co ma wpływ na buforowanie, chyba że jest to system wielogniazdowy z oddzielnymi L3 i DRAM) dla każdego klastra procesorów, i masz procesy przypięte do rdzeni, więc jedno kodowanie używa rdzeni w jednym gnieździe, a drugie w drugim).

Komentarze

  • Dziękujemy za wgląd. Zadałem tutaj pytanie głównie dlatego, że ' nie mam żadnych pytań dotyczących kodu ” ” i więcej o tym, co dzieje się za kulisami, i pomyślałem, że to będzie lepiej pasować. Oznaczam ', aby moderatorzy mogli się zmigrować i wtedy mogą zadzwonić.
  • W tej chwili ' ponowne umieszczenie wiadomości w kolejce AWS SQS, która ma łącze do każdego pliku. Ta instancja ma uruchomione zadanie, które nasłuchuje tych komunikatów, pobiera plik, transkoduje go i przesyła pliki wyjściowe po zakończeniu każdego z nich. Jeśli dobrze to czytam, ' mówisz, że prawdopodobnie bardziej sensowne byłoby uruchomienie kilku z tych procesów roboczych i transkodowanie wielu plików równolegle zamiast próbować skupić wszystkie rdzenie na jednym procesie?
  • Tak, jeśli ' masz problemy z nasyceniem większej liczby rdzeni, oznacza to ' dobrze jest uruchomić kodowanie lub 3 równolegle. Myślę, że x264 powinien być w stanie nasycić większość z twoich 32 rdzeni, ale może tylko z wolniejszym ustawieniem. Opublikuj w swoim pytaniu opcje polecenia ffmpeg cmdline i dane wyjściowe konsoli. IDK, jeśli ' używasz czegoś głupiego i niskiej jakości, takiego jak -preset veryfast. Jeśli tak, to dekodowanie wejścia może być wąskim gardłem jednego wątku. Albo, jak powiedziałem, może powolny filtr.
  • Ty ' z pewnością będziesz chciał nałożyć pobieranie / przesyłanie jednego xcode z użyciem procesora innego xcode, jeśli ' nie planujesz przesyłania strumieniowego do / z ffmpeg w locie do użytku produkcyjnego. ( Może będzie możliwe uzyskanie w locie odpowiednika -movflags +faststart z innym mukserem. Myślę, że coś o tym czytałem. W przeciwnym razie, jeśli ' w przypadku wyprowadzania pliku mp4, musisz wyprowadzić plik do pliku, aby ffmpeg mógł umieścić atom moov z przodu i przetasować dane kiedy kodowanie jest zakończone.)
  • Och, po prostu przeczytałem twój Q bardziej szczegółowo. Jeśli ' ponownie wyprowadzasz wszystkie 3 formaty za jednym razem (z tą samą linią poleceń ffmpeg, więc dekodowanie wejścia musi nastąpić tylko raz), to jeśli jeden z 3 koderów jest jednowątkowy, będzie wąskim gardłem całego procesu. Myślę, że libtheora nie jest wielowątkowa. wiki.xiph.org/TheoraEncoders podaje, że istnieje rozwidlenie wielowątkowe, ale umarło. (może nigdy nie działał dobrze lub nie ' nie był kompatybilny z innymi ulepszeniami kodera? Może być wiele powodów, dla których nie ' nie został scalony). lists.xiph.org/pipermail//theora-dev/2015-Feb February/004374.html

Odpowiedź

libtheora jest jednowątkowa. Istnieje wielowątkowa eksperymentalna kompilacja, ale nie jest ona obsługiwana. Sugerowałbym uruchomienie go równolegle z innymi kodami. Jeśli to możliwe, użyj libfdk-aac zamiast libfaac.Znacznie wyższa wierność dźwięku przy tej samej szybkości transmisji.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *