Qual è il modo corretto di correggere i fotogrammi chiave in FFmpeg per DASH?


38

Quando si condiziona un flusso per la riproduzione DASH, i punti di accesso casuali devono trovarsi esattamente allo stesso tempo del flusso sorgente in tutti i flussi. Il solito modo per farlo è forzare un frame rate fisso e una lunghezza GOP fissa (cioè un fotogramma chiave ogni N frame).

In FFmpeg, la frequenza dei fotogrammi fissa è semplice (-r NUMERO).

Ma per le posizioni dei fotogrammi chiave fissi (lunghezza GOP), ci sono tre metodi ... quale è "corretto"? La documentazione di FFmpeg è frustrantemente vaga al riguardo.

Metodo 1: pasticciare con gli argomenti di libx264

-c:v libx264 -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE:scenecut=-1

Sembra esserci un dibattito se lo scenecut debba essere disattivato o meno, poiché non è chiaro se il "contatore" del fotogramma chiave viene riavviato quando si verifica un taglio della scena.

Metodo 2: impostazione di una dimensione GOP fissa:

-g GOP_LEN_IN_FRAMES

Questo è purtroppo documentato solo passando nella documentazione di FFMPEG, e quindi l'effetto di questo argomento è molto poco chiaro.

Metodo 3: inserire un fotogramma chiave ogni N secondi ( forse? ):

-force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)

Questo è esplicitamente documentato. Ma non è ancora immediatamente chiaro se il "contatore del tempo" si riavvia dopo ogni fotogramma chiave. Ad esempio, in un GOP di 5 secondi previsto, se vi è un scenecutfotogramma chiave iniettato per 3 secondi da libx264, il fotogramma chiave successivo sarebbe 5 secondi dopo o 2 secondi dopo?

In effetti, la documentazione di FFmpeg differenzia tra questa e l' -gopzione, ma in realtà non dice come queste due opzioni sopra siano le meno diverse (ovviamente, -grichiederà una frequenza di fotogrammi fissa).

Quale è giusto?

Sembrerebbe che -force_key_framessarebbe superiore , in quanto non richiederebbe un frame rate fisso. Tuttavia, questo richiede questo

  • è conforme alle specifiche GOP in H.264 ( se presenti )
  • GARANTISCE che ci sarebbe un fotogramma chiave in cadenza fissa, indipendentemente dai scenecutfotogrammi chiave libx264 .

Sembrerebbe anche che -gnon possa funzionare senza forzare una frequenza dei fotogrammi fissa ( -r) , poiché non esiste alcuna garanzia che sequenze multiple ffmpegcon argomenti di codec diversi fornirebbero la stessa frequenza di fotogrammi istantanea in ciascuna risoluzione. Frame rate fissi possono ridurre le prestazioni di compressione (IMPORTANTE in uno scenario DASH!).

Infine, il keyintmetodo sembra solo un trucco . Spero contro la speranza che questa non sia la risposta corretta.

Riferimenti:

Un esempio che utilizza il -force_key_framesmetodo

Un esempio che utilizza il keyintmetodo

FFmpeg sezione opzioni video avanzate

Risposte:


27

TL; DR

Consiglierei quanto segue:

  • libx264: (e facoltativamente aggiungere )-g X -keyint_min X-force_key_frames "expr:gte(t,n_forced*N)"
  • libx265: -x265-params "keyint=X:min-keyint=X"
  • libvpx-vp9: -g X

dove Xè l'intervallo in frame ed Nè l'intervallo in secondi. Ad esempio, per un intervallo di 2 secondi con un video a 30 fps, X= 60 e N= 2.

Una nota sui diversi tipi di frame

Per spiegare correttamente questo argomento, dobbiamo prima definire i due tipi di I-frame / keyframe:

  • Frame di aggiornamento decodificatore istantaneo (IDR): consentono la decodifica indipendente dei seguenti frame, senza accesso ai frame precedenti al frame IDR.
  • Frame non IDR: richiedono un frame IDR precedente affinché la decodifica funzioni. I fotogrammi non IDR possono essere utilizzati per i tagli di scena nel mezzo di un GOP (gruppo di immagini).

Cosa è raccomandato per lo streaming?

Per il caso di streaming, si desidera:

  • Assicurati che tutti i frame IDR siano in posizioni regolari (ad esempio a 2, 4, 6, ... secondi) in modo che il video possa essere suddiviso in segmenti di uguale lunghezza.
  • Abilita il rilevamento del taglio della scena, in modo da migliorare l'efficienza / la qualità della codifica. Ciò significa consentire il posizionamento di I-frame tra i frame IDR. Puoi ancora lavorare con il rilevamento del taglio della scena disabilitato (e questo fa parte di molte guide, ancora), ma non è necessario.

Cosa fanno i parametri?

Per configurare l'encoder, dobbiamo capire cosa fanno i parametri del fotogramma chiave. Ho fatto alcuni test e scoperto i seguenti, per i tre encoder libx264, libx265e libvpx-vp9in FFmpeg:

  • libx264:

    • -g imposta l'intervallo del fotogramma chiave.
    • -keyint_min imposta l'intervallo minimo di fotogrammi chiave.
    • -x264-params "keyint=x:min-keyint=y"è lo stesso di -g x -keyint_min y.
    • Nota: quando si impostano entrambi sullo stesso valore, il minimo viene impostato internamente a metà dell'intervallo massimo più uno, come si vede nel x264codice:

      h->param.i_keyint_min = x264_clip3( h->param.i_keyint_min, 1, h->param.i_keyint_max/2+1 );
      
  • libx265:

    • -g non è implementato.
    • -x265-params "keyint=x:min-keyint=y" lavori.
  • libvpx-vp9:

    • -g imposta l'intervallo del fotogramma chiave.
    • -keyint_min imposta l'intervallo minimo di fotogrammi chiave
    • Nota: a causa del funzionamento di FFmpeg, -keyint_minviene inoltrato all'encoder solo quando è uguale a -g. Nel codice di libvpxenc.cin FFmpeg possiamo trovare:

      if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
          enccfg.kf_min_dist = avctx->keyint_min;
      if (avctx->gop_size >= 0)
          enccfg.kf_max_dist = avctx->gop_size;
      

      Questo potrebbe essere un bug (o mancanza di funzionalità?), Poiché libvpxsupporta sicuramente l'impostazione di un valore diverso per kf_min_dist.

Dovresti usare -force_key_frames?

L' -force_key_framesopzione inserisce forzatamente i fotogrammi chiave all'intervallo specificato (espressione). Funziona con tutti gli encoder, ma potrebbe interferire con il meccanismo di controllo della frequenza. Soprattutto per VP9, ​​ho notato forti fluttuazioni di qualità, quindi non posso raccomandare di usarlo in questo caso.


Grazie! Questo è un ottimo feedback. Una domanda che ho è come hai generato quel fantastico tavolo. Potrei usare totalmente qualcosa del genere.
Mark Gerolimatos,

(Sembra che non ci sia modo di scriverti direttamente) Puoi per favore indicarmi i collegamenti a qualsiasi thread in questa discussione ITU-T? Grazie!
Mark Gerolimatos,

2
L'ho appena fatto in Excel, incollando l'output ottenuto da tre serie di ffprobe -i input.mp4 -select_streams v -show_frames -of csv -show_entries frame=pict_type, quindi colorando le celle. Temo che non ci siano discussioni pubbliche, ma vedrò se riesco a trovare alcuni dei collegamenti che ho trovato allora.
slhck,

Potresti riprovare l'esperimento con il -force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)modulo? L'ho appena provato e ho scoperto che mentre c'erano altri frame I nel flusso, DID sembrava rispettare la mia regola. Un programma PERL seguirà come "risposta", poiché apparentemente non è possibile utilizzare il markup nei commenti.
Mark Gerolimatos,

Interessante. Credo che valga una risposta "reale" separata se scopri che funziona. (I siti Stack Exchange non sono molto utili per questa risposta in stile discussione.) L'ultima volta che ho controllato, -force_key_framesnon ha funzionato per me, quindi non l'ho mai più provato. È stato più di un anno fa. Forse era un bug. Ci riproverò presto.
slhck,

12

Ecco i miei cinquanta centesimi per il caso.

Metodo 1:

pasticciare con gli argomenti di libx264

-c: v libx264 -x264opts keyint = GOPSIZE: min-keyint = GOPSIZE: scenecut = -1

Genera iframe solo agli intervalli desiderati.

Esempio 1:

ffmpeg -i test.mp4 -codec:v libx264 \
-r 23.976 \
-x264opts "keyint=48:min-keyint=48:no-scenecut" \
-c:a copy \
-y test_keyint_48.mp4

Genera iframe come previsto in questo modo:

Iframes     Seconds
1           0
49          2
97          4
145         6
193         8
241         10
289         12
337         14
385         16
433         18
481         20
529         22
577         24
625         26
673         28
721         30
769         32
817         34
865         36
913         38
961         40
1009        42
1057        44
1105        46
1153        48
1201        50
1249        52
1297        54
1345        56
1393        58

Il metodo 2 è ammortizzato. Omesso.

Metodo 3:

inserire un fotogramma chiave ogni N secondi (FORSE):

-force_key_frames expr: gte (t, n_ced * GOP_LEN_IN_SECONDS)

Esempio 2

ffmpeg -i test.mp4 -codec:v libx264 \
-r 23.976 \
-force_key_frames "expr:gte(t,n_forced*2)"
-c:a copy \
-y test_fkf_2.mp4

Genera un iframe in un modo leggermente diverso:

Iframes     Seconds
1           0
49          2
97          4
145         6
193         8
241         10
289         12
337         14
385         16
433         18
481         20
519         21.58333333
529         22
577         24
625         26
673         28
721         30
769         32
817         34
865         36
913         38
931         38.75
941         39.16666667
961         40
1008        42
1056        44
1104        46
1152        48
1200        50
1248        52
1296        54
1305        54.375
1344        56
1367        56.95833333
1392        58
1430        59.58333333
1440        60
1475        61.45833333
1488        62
1536        64
1544        64.33333333
1584        66
1591        66.29166667
1632        68
1680        70
1728        72
1765        73.54166667
1776        74
1811        75.45833333
1824        75.95833333
1853        77.16666667
1872        77.95833333
1896        78.95833333
1920        79.95833333
1939        80.75
1968        81.95833333

Come puoi vedere posiziona iframe ogni 2 secondi E su scenecut (secondi con parte mobile) che è importante per la complessità del flusso video secondo me.

Le dimensioni dei file generati sono praticamente le stesse. Molto strano che anche con più fotogrammi chiave nel Metodo 3 generi a volte meno file dell'algoritmo standard della libreria x264.

Per generare più file bitrate per il flusso HLS scegliamo il metodo tre. È perfettamente allineato con 2 secondi tra i blocchi, hanno iframe all'inizio di ogni blocco e hanno iframe aggiuntivi su scene complesse che offrono un'esperienza migliore agli utenti che hanno dispositivi obsoleti e non possono riprodurre profili alti x264.

Spero che aiuti qualcuno.


Fantastico, grazie per i tuoi 50 centesimi!
BrunoFenzl,

7

La risposta quindi sembra essere:

  • Il metodo 1 è verificato per funzionare, ma è libx264-specifico e ha il costo di eliminare l' scenecutopzione molto utile in libx264.
  • Il metodo 3 funziona a partire dalla versione FFMPEG di aprile 2015, ma è necessario verificare i risultati con lo script incluso nella parte inferiore di questo post, poiché la documentazione di FFMPEG non è chiara in merito all'effetto dell'opzione. Se funziona, è la superiore delle due opzioni.
  • NON UTILIZZARE il metodo 2, -gsembra essere obsoleto. Non sembra funzionare, né è esplicitamente definito nella documentazione, né si trova nella guida, né sembra essere utilizzato nel codice. L'ispezione del codice mostra che l' -gopzione è probabilmente pensata per i flussi MPEG-2 (ci sono persino stanze di codice che si riferiscono a PAL e NTSC!).

Anche:

  • I file generati con il metodo 3 possono essere leggermente più grandi del metodo 1, poiché sono consentiti i frame interstiziali I (fotogrammi chiave).
  • Dovresti impostare esplicitamente il flag "-r" in entrambi i casi, anche se il Metodo 3 posiziona un frame I al prossimo framelot il o dopo il tempo specificato. La mancata impostazione del flag "-r" ti mette in balia del file di origine, possibilmente con una frequenza dei fotogrammi variabile. Potrebbero verificarsi transizioni DASH incompatibili.
  • Nonostante gli avvertimenti nella documentazione di FFMPEG, il metodo 3 NON è meno efficiente di altri. In effetti, i test dimostrano che potrebbe essere leggermente PIÙ efficiente rispetto al metodo 1.

Script per l' -force_key_framesopzione

Ecco un breve programma PERL che ho usato per verificare la cadenza I-frame in base all'output del suggerimento ffprobe di slhck. Sembra verificare che anche il -force_key_framesmetodo funzionerà e ha l'ulteriore vantaggio di consentire i scenecutframe. Non ho assolutamente idea di come FFMPEG funzioni, o se ho avuto fortuna in qualche modo perché i miei flussi sono ben condizionati.

Nel mio caso, ho codificato a 30 fps con una dimensione GOP prevista di 6 secondi o 180 fotogrammi. Ho usato 180 come argomento gopsize per questo programma verificato un frame I per ogni multiplo di 180, ma impostandolo su 181 (o qualsiasi altro numero non multiplo di 180) lo ha fatto lamentare.

#!/usr/bin/perl
use strict;
my $gopsize = shift(@ARGV);
my $file = shift(@ARGV);
print "GOPSIZE = $gopsize\n";
my $linenum = 0;
my $expected = 0;
open my $pipe, "ffprobe -i $file -select_streams v -show_frames -of csv -show_entries frame=pict_type |"
        or die "Blah";
while (<$pipe>) {
  if ($linenum > $expected) {
    # Won't catch all the misses. But even one is good enough to fail.
    print "Missed IFrame at $expected\n";
    $expected = (int($linenum/$gopsize) + 1)*$gopsize;
  }
  if (m/,I\s*$/) {
    if ($linenum < $expected) {
      # Don't care term, just an extra I frame. Snore.
      #print "Free IFrame at $linenum\n";
    } else {
      #print "IFrame HIT at $expected\n";
      $expected += $gopsize;
    }
  }
  $linenum += 1;
}

Solo una nota: poiché si tratta di un sito di domande e risposte e non di un vero forum di discussione in cui i post sono ordinati cronologicamente, è meglio mettere tutte le informazioni in una risposta, in modo che le persone in cerca di una soluzione debbano solo leggere un post e non guardare a chi ha pubblicato cosa, quando :) Ho unito le tue risposte e ti ho dato un +1 anche su questo. Dal momento che il cross posting non è consentito , ti suggerisco di eliminare la tua domanda sul sito del video. Le persone troveranno le risposte qui.
slhck,

1
Ho solo avuto un altro pensiero (in realtà è stato raccolto nella mailing list di FFmpeg). Quando lo usi force_key_frames, in qualche modo confonde l'algoritmo di allocazione dei bit x264, quindi potrebbe darti una qualità peggiore rispetto alla semplice impostazione di un intervallo di fotogrammi chiave fisso.
slhck,

Merda santa. Tuttavia, un motivo in più per fare in modo che FFMPEG fornisca un modo non specifico di codec per farlo, un argomento che "farebbe la cosa migliore per il codec in questione". Ho provato a presentare un biglietto per questo con il trac di FFMPEG, ma il rimbalzo :-(
Mark Gerolimatos,

@slhck: potresti fornire maggiori dettagli per favore? Ho guardato negli archivi della mailing list a maggio 2015 ma non sono riuscito a trovare nulla. La linea di fondo sarebbe dimenticare "Metodo 3" e attenersi a "Metodo 1".
schieferstapel,

3
@MarkGerolimatos: circa -g, dici, "Non sembra funzionare, ... né sembra essere usato nel codice.". Ho controllato e l'ingresso gè memorizzato in avctx->gop_sizee che marchi libx264 uso di esso: x4->params.i_keyint_max = avctx->gop_size;. Quando sondare questo file di test generato ffmpeg -i a-test-file.mp4 -g 37 -t 15 gtest.mp4:, ottengo i fotogrammi chiave esattamente 0,37,74,111,148,185,222,259,296,333,370. Un GOP potrebbe essere abbreviato se viene attivato il cambio di scena, e per questo -sc_thresholdpotrebbe essere impostato, che viene anche preso da x264.
Gyan

4

Volevo aggiungere alcune informazioni qui dal momento che il mio googling ha sollevato un po 'questa discussione nella mia ricerca per trovare informazioni su come cercare di trovare un modo per segmentare la mia codifica DASH nel modo desiderato, e nessuna delle informazioni che ho trovato era totalmente corretta.

Primi diversi malintesi per sbarazzarsi di:

  1. Non tutti gli I-frame sono uguali. Ci sono grandi cornici "I" e piccole cornici "i". O per utilizzare una terminologia corretta, ID-frame IDR e I-frame non IDR. I-frame IDR (a volte chiamati "fotogrammi chiave") creeranno un nuovo GOP. I frame non IDR no. Sono utili per avere all'interno di un GOP dove c'è un cambio di scena.

  2. -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE← Questo non fa ciò che pensi che faccia. Mi ci è voluto un po 'di tempo per capire. Si scopre che min-keyintè limitato nel codice. Non è consentito essere maggiore di (keyint / 2) + 1. Quindi assegnare lo stesso valore a queste due variabili si traduce in un valore che min-keyintviene ridotto della metà durante la codifica.

Ecco la cosa: il taglio della scena è davvero eccezionale, specialmente nei video che hanno tagli rapidi e veloci. Lo mantiene bello e nitido, quindi non voglio disabilitarlo, ma allo stesso tempo non sono riuscito a ottenere una dimensione GOP fissa finché è stato abilitato. Volevo abilitare il taglio della scena, ma per farlo usare solo I-frame non IDR. Ma non funzionava. Fino a quando non ho capito (da molte letture) l'idea sbagliata n. 2.

Si scopre che dovevo impostare il keyintdoppio della dimensione GOP desiderata. Ciò significa che min-keyintpuò essere impostato sulla dimensione GOP desiderata (senza che il codice interno lo tagli a metà), il che impedisce al rilevamento del taglio della scena di utilizzare i fotogrammi I IDR all'interno della dimensione GOP perché il conteggio dei fotogrammi dall'ultimo I-frame IDR è sempre meno di min-keyinit.

E infine l'impostazione force_key_framedell'opzione ha la precedenza sulla doppia dimensione keyint. Quindi, ecco cosa funziona:

Preferisco i segmenti in blocchi di 2 secondi, quindi il mio GOPSIZE = Framerate * 2

ffmpeg <other_options> -force_key_frames "expr:eq(mod(n,<GOPSIZE>),0)" -x264opts rc-lookahead=<GOPSIZE>:keyint=<GOPSIZE * 2>:min-keyint=<GOPSIZE> <other_options>

Puoi verificare usando ffprobe:

ffprobe <SRC_FLE> -select_streams v -show_frames -of csv -show_entries frame=coded_picture_number,key_frame,pict_type > frames.csv

Nel file CSV generato ogni riga ti dirà frame, [is_an_IDR_?], [frame_type], [frame_number]:

frame,1,I,60  <-- frame 60, is I frame, 1 means is an IDR I-frame (aka KeyFrame)
frame,0,I,71  <-- frame 71, is I frame, 0 means not an IDR I_frame

Il risultato è che dovresti vedere gli I-frame IDR solo a GOPSIZEintervalli fissi , mentre tutti gli altri frame I sono frame I non IDR inseriti come richiesto dal rilevamento del taglio della scena.


è stato fantastico! È stato anche molto controintuitivo, grazie per averci messo lo sforzo. E per riassumere, presumo che la tua definizione di "I-frame" e "i-frame" sia concettuale (cioè non configurabile in modo esplicito in libx264), e che il "max * 2" era il modo in cui l'hai applicato?
Mark Gerolimatos,

Sì, quello era concettuale, anche se ho visto le persone usare "I" vs "i" per distinguere tra frame I IDR e non IDR. E sì, impostare keyinit sulla dimensione gop desiderata * 2 è un modo per forzare tutti i frame I all'interno del gop ad essere frame I non IDR. Quindi ffmpeg -force-key-frame sovrascrive key-init in x264opts. Fondamentalmente è un modo davvero arretrato per ottenere il risultato desiderato che sarebbe possibile se il codice x264 ti permettesse di impostare min-keyinit e keyinit sullo stesso valore.
Reuben,

... pur essendo in grado sia di attivare il rilevamento del taglio della scena sia di ottenere dimensioni GOP fisse.
Reuben,

grazie ancora per il tuo fantastico lavoro! Sembra che abbiamo bisogno di un modo meno "arretrato" per realizzarlo
Mark Gerolimatos,

Qui è necessario rc-lookahead? Colpisce mbtree e VBV, ma influenza la generazione di i-frame?
Alexander Svetkin,

0

Sembra che questa sintassi non funzioni sempre .. Ho testato parecchio sul nostro contenuto VOD e sul contenuto live (dump di file) e talvolta scenecut non funziona e attiva un iframe intermedio:

Sintassi per upconvertion i50-> p50, gop / segmento di 2 secondi, IDR all'inizio, iframe tra di loro se necessario

ffmpeg.exe -loglevel verbose -i avc_50i.ts -pix_fmt yuv420p -filter_complex yadif=1,scale=1920:1080 -vcodec libx264 -preset fast -x264-params "rc-lookahead=100:keyint=200:min-keyint=100:hrd=1:vbv_maxrate=12000:vbv_bufsize=12000:no-open-gop=1" -r 50 -crf 22 -force_key_frames "expr:eq(mod(n,100),0)" -codec:a aac -b:a 128k -y target.ts

0

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.