Abbiamo sviluppato unapplicazione per transcodificare i file .mov sorgente in output .ogg, .mp4 e .webm. Attualmente è in esecuzione sullistanza AWS EC2 g2.8xlarge. Funziona (yay!).

La mia domanda: anche se sto passando -threads 0 al comando ffmpeg (attualmente impostando ffmpeg.threads configurazione in php-ffmpeg ), il processo in esecuzione a volte viene eseguito solo su un singolo core. Perché sta succedendo? Vedi sotto loutput dal comando htop:

htop output

Come puoi vedere , Core # 21 è al massimo. In pochi secondi, passerà a un altro, invece di portarli al massimo come vorrei e velocizzerà notevolmente il mio processo di codifica. La situazione è transitoria; durante alcune esecuzioni tutti i processori sono al massimo, ma in altri casi non lo sono e utilizziamo solo un processore. Un collega ha detto che forse il codec che stiamo utilizzando per alcuni formati non supporta lesecuzione multi-thread durante la codifica, anche se non posso ancora verificare che sia il comportamento che sto ancora osservando.

È così? In tal caso, quali codec per i formati sopra ci consentiranno di transcodificare in questi formati di destinazione sfruttando tutto il nostro hardware disponibile? I codec predefiniti impostati per php-ffmpeg sono di seguito;

 Video Audio Ogg libtheora libvorbis WebM libvpx libvorbis X264 libx264 libfaac 

Aggiorna

Guardando i processi in esecuzione, di seguito è riportato ciò che finisce per essere il comando ffmpeg eseguito per un MP4 (attualmente saturando tutti i 32 core):

In realtà non sto creando questo comando direttamente, php-ffmpeg lo è, anche se credo di avere almeno un modesto controllo su ciò che funziona (ad esempio, non ho idea del motivo per cui ci sono più -metadata:s:v:0 voci allinizio)

Commenti

  • Cè ‘ un sacco di schifo in quella riga di comando, a parte le opzioni duplicate (-s tre volte , quello finale di misura diversa). Impostazione esplicita di una serie di argomenti sui valori predefiniti correnti (ad es. -i_qfactor, -subq, -qcomp) è strano e potrebbe dare cattivi risultati con la futura libx264. (Probabilmente no, ma solo perché libx264 è praticamente fatto, e stabile, non in fase di sviluppo pesante. Se facesse cose del genere per x265, sarebbe un male.) Ad ogni modo, 1200k a 2 passaggi va bene, ma potresti preferire target -qualità crf. Non ‘ specifica un -preset. 🙁
  • libfaac non è ‘ buono come libfdk_aac Tuttavia, se ‘ lo utilizzi in un servizio a pagamento, ‘ dovresti controllare la licenza di libfdk_aac. Inoltre, questo cmdline manca -movflags +faststart
  • È ‘ anche possibile fare in modo che ffmpeg produca più output dallo stesso input. Basta avere più sequenze di opzioni di output nome-file di output sulla riga di comando. Quindi, tutto sommato, ‘ non sono molto impressionato da php-ffmpeg, se ‘ è il tipo di cmdline con cui viene prodotto. Forse potresti usarlo in modo diverso per generare più output contemporaneamente, quindi non ‘ essere un passaggio di theora a thread singolo. Ad ogni modo, se funziona, allora ottimo, ma attenzione alle modifiche ai valori predefiniti del codificatore e al significato dei subme livelli di x264 che cambiano, in modi che io e il tuo cmdline fa male alla qualità.
  • @Peter grazie mille. Penso che la risposta qui sia davvero che ho bisogno di eseguire il debug di come viene costruito quel cmd. Se davvero posso inserire più output in quel comando, penso che probabilmente mi darebbe la possibilità migliore di massimizzare il carico sullhardware
  • trac.ffmpeg .org / wiki / Creazione di% 20multiple% 20output . E sì, sono daccordo che ‘ è probabilmente il migliore. Altrimenti hai il compito che ‘ è a thread singolo per un po del suo tempo e carica tutti i tuoi core per unaltra parte del tempo. Difficile programmare lavori che si comportano in questo modo.

Rispondi

A proposito, questa domanda potrebbe essere migliore su stackoverflow, o forse unix.stackexchange, o forse serverfault. Penso che questo sito sia meno focalizzato su domande che non implicano decisioni basate sul merito creativo o almeno sulla qualità video / audio percettiva. Tuttavia, mi occupo dei dettagli tecnici, quindi risponderò.

FFmpeg utilizza il multi-threading per impostazione predefinita, quindi probabilmente non è necessario -threads 0. Se la tua codifica ha un collo di bottiglia su un filtro o decodificatore a thread singolo, vedrai il pieno carico su un core e un carico leggero su molti altri core.

Una cosa che puoi fare è controllare mediainfo del tuo video di output. x264 lascia le sue impostazioni in una stringa ASCII nellintestazione h.264. Quindi strings -n20 o mediainfo per ottenere:

... 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 

Nota i “thread = 4” lì dentro. Penso di averlo impostato manualmente sul mio quad core i5 2500k, invece di lasciare che x264 utilizzi le CPU predefinite * 1.5, poiché avevo in esecuzione filtri ad alta intensità di CPU (hqdn3d e lanczos-downscale).

Comunque, libx264 con un preset come slower dovrebbe avere nessun problemi a tenere occupati molti core. Ci sono alcune parti della codifica che sono intrinsecamente seriali (ad es. La codifica CABAC del bitstream finale), quindi un video a bitrate elevato che non impiega molti riferimenti per il perfezionamento del tempo della CPU (alto subme) a più frame (high ref) potrebbe mostrare uno schema di caricamento come il tuo (un thread che utilizza il 100% della CPU, altri no).

I “Non sono sicuro al 100% che i preset più veloci siano meno paralleli, ma so che CABAC è seriale.

Per ottenere un enorme parallelismo, libx264 potrebbe utilizzare un carico di RAM per mantenere i frame e continuare a guardare avanti per 2 o più GOP e codificali in modo indipendente. Tuttavia, non ha la possibilità di operare in questo modo.

Un modo per utilizzare MOLTI core è eseguire più codifiche separate in parallelo, invece di una serie di codifiche singole utilizzando tutti i core. Funziona solo se hai più file di input che desideri codificare separatamente. Stai scambiando il sovraccarico del threading con una maggiore capacità di memoria e larghezza di banda (con un impatto sulla memorizzazione nella cache, a meno che non si tratti di un sistema multi-socket con L3 e DRAM separati per ogni cluster di CPU, e hai i processi fissati ai core in modo che una codifica utilizzi i core in un socket e laltra nellaltro).

Commenti

  • Grazie per lapprofondimento. Ho chiesto qui principalmente perché ‘ non ho alcuna domanda in merito al ” codice ” e altro su cosa sta succedendo dietro le quinte e ho pensato che sarebbe stato più adatto. ‘ contrassegno per consentire allattenzione del moderatore di migrare e lui potrà effettuare la chiamata.
  • In questo momento ‘ re attaccare un messaggio su una coda AWS SQS che ha un collegamento a ogni file. Questa istanza ha un lavoro in esecuzione che ascolta quei messaggi, scarica il file, lo transcodifica e carica i file di output al termine di ciascuno. Se sto leggendo correttamente, ‘ stai dicendo che probabilmente avrebbe più senso per noi avviare alcuni di questi processi di lavoro e transcodificare più file in parallelo anziché tentare di concentrare tutti i core su un singolo processo?
  • Sì, se ‘ hai problemi a saturare più core, ‘ va bene per eseguire una codifica o 3 in parallelo. Penso che x264 dovrebbe essere in grado di saturare la maggior parte dei tuoi 32 core, ma forse solo con un preset più lento. Pubblica le tue opzioni cmdline ffmpeg e loutput della console nella tua domanda. IDK se ‘ stai usando qualcosa di sciocco e di bassa qualità come -preset veryfast. In tal caso, la decodifica dellinput potrebbe essere il collo di bottiglia a thread singolo. O come ho detto, forse un filtro lento.
  • Tu ‘ vorrai sicuramente sovrapporre il download / upload di un xcode con lutilizzo della CPU di un altro xcode, se ‘ non hai intenzione di trasmettere in streaming a / da ffmpeg al volo per lutilizzo in produzione. ( potrebbe essere possibile ottenere lequivalente di -movflags +faststart al volo, con un diverso muxer. Penso di aver letto qualcosa al riguardo. Altrimenti, se tu ‘ riproducendo mp4, è necessario eseguire loutput in un file in modo che ffmpeg possa mettere latomo moov in primo piano e mescolare i dati quando la codifica è terminata.)
  • Oh, ho appena letto la tua Q in modo più dettagliato. Se ‘ riproduci tutti e 3 i formati in una volta sola (con la stessa riga di comando ffmpeg, quindi la decodifica dellinput deve avvenire solo una volta), allora se uno dei 3 codificatori è a thread singolo, ostacolerà lintero processo. Penso che libtheora non sia multi-thread. wiki.xiph.org/TheoraEncoders dice che cera un fork multi-thread, ma è morto. (forse non ha mai funzionato bene o ‘ t compatibile con altri miglioramenti del codificatore? Potrebbero essere molte le ragioni per cui ‘ non è stato unito.) lists.xiph.org/pipermail//theora-dev/2015-February/004374.html

Risposta

libtheora è a thread singolo. Esiste una build sperimentale multithread, ma non viene mantenuta. Suggerirei di eseguirlo in parallelo con le altre codifiche. Inoltre, se possibile, usa libfdk-aac su libfaac.Fedeltà audio molto più elevata allo stesso bitrate.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *