Twitch ha un post su questo. Spiegano che hanno deciso di utilizzare il proprio programma per diversi motivi; uno di questi era che ffmpeg non ti consente di eseguire diverse istanze x264 in thread diversi, ma invece dedica tutti i thread specificati a un frame in un output prima di passare all'output successivo.
Se non stai eseguendo lo streaming in tempo reale, hai più lusso. Il modo "corretto" è probabilmente quello di codificare a una risoluzione con solo la dimensione GOP specificata con -g, quindi codificare le altre risoluzioni forzando i fotogrammi chiave negli stessi punti.
Se si desidera farlo, è possibile utilizzare ffprobe per ottenere i tempi dei fotogrammi chiave e quindi utilizzare uno script di shell o un vero linguaggio di programmazione per convertirlo in un comando ffmpeg.
Ma per la maggior parte dei contenuti, c'è ben poca differenza tra avere un fotogramma chiave ogni 5 secondi e due fotogrammi chiave ogni 5 secondi (uno forzato e uno da sceneggiatura). Si tratta della dimensione media del fotogramma I rispetto alla dimensione dei fotogrammi P e dei fotogrammi B. Se usi x264 con impostazioni tipiche (l'unica ragione per cui penso che dovresti fare qualsiasi cosa per influenzarli è se imposti -qmin, come un cattivo modo per impedire a x264 di usare bitrate su contenuti facili; questo limita tutti i tipi di frame allo stesso valore , Penso) e ottengo un risultato come una dimensione media I-frame di 46 kB, frame P 24 kB, frame B 17 kB (metà frequente dei frame P), quindi un frame I aggiuntivo ogni secondo a 30 fps è solo un aumento del 3% nella dimensione del file. La differenza tra h264 e h263 potrebbe essere composta da un gruppo di diminuzioni del 3%, ma una sola non è molto importante.
Su altri tipi di contenuto, le dimensioni dei frame saranno diverse. Ad essere onesti, si tratta di complessità temporale e non di complessità spaziale, quindi non è solo un contenuto facile contro un contenuto difficile. Ma in generale, i siti di video in streaming hanno un limite di bitrate e il contenuto con I-frame relativamente grandi è un contenuto facile che verrà codificato ad alta qualità, indipendentemente dal numero di fotogrammi chiave aggiuntivi aggiunti. È uno spreco, ma questo spreco di solito non viene notato. Il caso più dispendioso è probabilmente un video che è solo un'immagine statica che accompagna una canzone, in cui ogni fotogramma chiave è esattamente lo stesso.
Una cosa di cui non sono sicuro è il modo in cui i fotogrammi chiave forzati interagiscono con il limitatore di velocità impostato con -maxrate e -bufsize. Penso che anche YouTube abbia avuto recenti problemi a configurare correttamente le impostazioni del buffer per garantire una qualità costante. Se stai usando solo le impostazioni di bitrate medio come possono vedere alcuni siti (dato che puoi esaminare le opzioni di x264 nell'intestazione / mov atom? Con un editor esadecimale), allora il modello di buffer non è un problema, ma se stai offrendo contenuti generati dagli utenti, il bitrate medio incoraggia gli utenti ad aggiungere una schermata nera alla fine del loro video.
L'opzione -g di Ffmpeg, o qualsiasi altra opzione di codifica che usi, è mappata sull'opzione specifica del codificatore. Quindi '-x264-params keyint = GOPSIZE' equivale a '-g GOPSIZE'.
Un problema con l'utilizzo del rilevamento scene è se preferisci i fotogrammi chiave vicino a numeri specifici per qualsiasi motivo. Se si specificano i fotogrammi chiave ogni 5 secondi e si utilizza il rilevamento scene, e c'è un cambio di scena a 4.5, allora dovrebbe essere rilevato, ma il fotogramma chiave successivo sarà a 9.5. Se il tempo continua ad aumentare in questo modo, potresti finire con i fotogrammi chiave a 42.5, 47.5, 52.5, ecc., Invece di 40, 45, 50, 55. Al contrario, se c'è un cambio di scena a 5.5, allora ci sarà un fotogramma chiave a 5 e 5.5 sarà troppo presto per un altro. Ffmpeg non ti consente di specificare "crea un fotogramma chiave qui se non ci sono cambiamenti di scena nei prossimi 30 fotogrammi". Qualcuno che capisce C potrebbe aggiungere questa opzione, però.
Per i video a frequenza fotogrammi variabile, quando non sei in streaming live come Twitch, dovresti essere in grado di utilizzare i cambi di scena senza convertire permanentemente in frequenza fotogrammi costante. Se usi il filtro 'select' in ffmpeg e usi la costante 'scene' nell'espressione, l'output di debug (-v debug o premi '+' più volte durante la codifica) mostra il numero di cambio scena. Questo è probabilmente diverso e non altrettanto utile del numero usato da x264, ma potrebbe essere comunque utile.
La procedura, quindi, sarebbe probabilmente quella di fare un video di prova che è solo per le modifiche ai fotogrammi chiave, ma forse potrebbe essere usato per i dati di controllo della frequenza se si utilizza 2-pass. (Non sono sicuro che i dati generati siano affatto utili per risoluzioni e impostazioni diverse; i dati dell'albero dei macroblocchi non lo saranno.) Converti in video a framerate costanti, ma vedi questo bug su come balbettare l'output quando dimezzi framerate se decidi mai per utilizzare il filtro fps per altri scopi. Eseguilo su x264 con il fotogramma chiave e le impostazioni GOP desiderati.
Quindi basta usare questi tempi dei fotogrammi chiave con il video con frequenza dei fotogrammi variabile originale.
Se si consente il contenuto completamente folle generato dall'utente con uno spazio di 20 secondi tra i frame, quindi per la codifica con frame rate rate variabile, è possibile dividere l'output, utilizzare il filtro fps, in qualche modo utilizzare il filtro di selezione (forse creare un'espressione davvero lunga che ha ogni volta che si trova il fotogramma chiave) ... o forse è possibile utilizzare il video di prova come input e decodificare solo i fotogrammi chiave, se l'opzione ffmpeg funziona o utilizzare il filtro select per selezionare i fotogrammi chiave. Quindi ridimensionalo alla dimensione corretta (c'è anche un filtro scale2ref per questo) e sovrapponi il video originale su di esso. Quindi utilizzare il filtro interleave per combinare questi fotogrammi chiave forzati destinati al video originale. Se ciò si traduce in due frame distanti 0,001 secondi che il filtro interleave non impedisce, quindi risolvi questo problema con un altro filtro select. Gestire i limiti del buffer del frame per il filtro interleave potrebbe essere il problema principale qui. Tutti questi potrebbero funzionare: utilizzare un qualche tipo di filtro per bufferizzare il flusso più denso (filtro fifo?); fare riferimento al file di input più volte in modo che sia decodificato più di una volta e che i frame non debbano essere memorizzati; usare il filtro 'streamselect', cosa che non ho mai fatto, esattamente ai tempi dei fotogrammi chiave; migliorare il filtro interleave modificando il comportamento predefinito o aggiungendo un'opzione per produrre il frame più vecchio in un buffer invece di rilasciare un frame. cosa che non ho mai fatto, esattamente ai tempi dei fotogrammi chiave; migliorare il filtro interleave modificando il comportamento predefinito o aggiungendo un'opzione per produrre il frame più vecchio in un buffer invece di rilasciare un frame. cosa che non ho mai fatto, esattamente ai tempi dei fotogrammi chiave; migliorare il filtro interleave modificando il comportamento predefinito o aggiungendo un'opzione per produrre il frame più vecchio in un buffer invece di rilasciare un frame.