ffmpeg ha scritto in la domanda viene normalmente convogliata in un altro binario. Quel binario salva i frame forniti da ffmpeg e fa qualche elaborazione su di essi.
All'inizio ho provata "fifo_size = 1000000 & overrun_nonfatal = 1" opzioni, e mi è stato sempre seguente errore da ffmpeg
[udp @ 0x4ceb8a0] Circular buffer overrun. To avoid, increase fifo_size URL option. To survive in such case, use overrun_nonfatal option
udp://192.168.15.50:3200: Input/output error
e poi ffmpeg potrebbe andare in crash. Per evitarlo ho aggiunto "fifo_size = 1000000 & overrun_nonfatal = 1", come suggerisce ffmpeg.
Tuttavia, dopo aver utilizzato questi parametri, otterrei il timeshift come descritto in questione, ea volte anche con gli artefatti nei frame.
Come accennato, non ci sono stati problemi con la CPU. quindi inizialmente, si sospetta il flusso UDP, specificamente udp dimensione del buffer:
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Administration_And_Configuration_Guide/jgroups-perf-udpbuffer.html
quindi abbiamo cambiato dimensione del buffer UDP con:
sysctl -w net.core.rmem_max=26214400
e cambiato comando ffmpeg per "udp: //231.20 .20.8: 2005? Buffer_size = 26214400 "
tuttavia, questo non ha risolto il problema. ffmpeg otterrebbe ancora "sovraccarico del buffer circolare" e crash. E non potevo riprodurre questo sovraccarico di buffer circolare, stava accadendo casualmente.
mio pensiero successivo è stato la dimensione del buffer del tubo in quanto ho trovato seguendo:
http://blog.dataart.com/linux-pipes-tips-tricks/ La dimensione del buffer dal kernel versione 2.6.11 è 65536 byte (64K) ed è uguale alla memoria di pagina in vecchi kernel. Quando si tenta di leggere da un buffer vuoto, il processo di lettura è bloccato fino alla visualizzazione dei dati. Allo stesso modo, se si tenta di scrivere su un buffer completo, il processo di registrazione verrà bloccato fino a quando non sarà disponibile la quantità di spazio necessaria. http://ffmpeg.gusari.org/viewtopic.php?f=12&t=624 Poster1: Che cosa causa questi sovraccarichi di buffer circolare? La mia ipotesi è che ffmpeg stia leggendo il flusso di input nel buffer circolare sopra menzionato, e il codice quindi generi il flusso di output che legge dallo stesso buffer. L'overrun si verifica quando il codice che genera l'output non tiene il passo con la velocità con cui viene scritto nel buffer, giusto? Poster2: Osservando il codice sorgente, sembra che il buffer trabocchi sia dall'input troppo veloce sia dall'output troppo lento (cpu? Lento). La tua ipotesi è corretta.
Quindi la teoria era che il nostro file binario non legge abbastanza veloce. Come risultato la pipe viene bloccata e ffmpeg non può scrivere su di essa, e QUESTO risulta in overpump del buffer udp fifo (ffmpeg continua a leggere udp INTO FIFO, ma non può scrivere da esso nella nostra pipe)
Sono riuscito a dimostrare questa teoria con in esecuzione (in terminali separati):
mkfifo mypipe
ffmpeg -loglevel debug -i "udp://192.168.15.50:3200?fifo_size=1000000&overrun_nonfatal=1" -r 8 -preset ultrafast -fflags nobuffer -vf scale=432:243 -f image2pipe -vcodec ppm pipe:1 > mypipe
cat <mypipe> /dev/null # run this for 10 seconds, allowing ffmpeg to start. then pause it with CTRL-Z and see ffmpeg crashing because it cannot read more udp stream
quindi la prossima è stata la ricerca del perché il nostro file binario a un certo punto smette di leggere la pipe. sembrava che non ci fosse alcun motivo, perché normalmente si limitava a leggere in memoria immediatamente dopo che qualcosa era finito.
tuttavia, è stato anche salvare i frame sul disco rigido. ea SOME POINT (a volte 12 minuti, a volte 15 ore), le operazioni del disco rallentavano a causa delle operazioni di lettura/scrittura (era bcache (SSD e HDD ibrido, utilizza SSD come cache). alcuni milioni di file da questa unità paralelly per il debug.
così la scrittura di file sul disco rigido occupato potrebbe bloccare temporaneamente il nostro binario dalla lettura del tubo di ingresso.
così motivo per UDP buffer circolare problema superamento e l'eventuale timeshift è stato un L'HDD e la soluzione teorica è SSD
Questa indagine è durata circa 3 settimane, quindi postare tutto questo nella speranza che almeno in parte possa aiutare qualcuno in futuro
aggiornamento a questo:
ho anche rilevato un altro strozzatura provocando lo stesso problema più avanti (sostituzione HDD non era sufficiente), che era tcp buffer overflow presa causata da postgres inserzioni sul back-end.
l'intera pipeline sembra che:
udp_videostream-> ffmpeg-> linux_pipe-> our_client_side_binary-> TCP-> our_server_side_binary-> Postgres
Postgres domande erano volte lento, che provocava il nostro server per leggere il socket TCP più lentamente di quanto our_binary ci stesse spingendo. di conseguenza, il socket TCP sarebbe stato bloccato (era massimo 4Mb), e come risultato, il client avrebbe bloccato la sua pipe di input, e come risultato di tale ffmpeg si sarebbe bloccato con questo errore CBO.