Apa yang dimaksud dengan 'Durasi lalu X.XXX terlalu besar'?

142

Saat menyandikan H.264 menggunakan ffmpeg saya mendapatkan jenis peringatan berikut ini secara massal:

Past duration 0.603386 too large
Past duration 0.614372 too large
Past duration 0.606377 too large

Apa yang mereka maksud? Saya belum menemukan sesuatu yang jelas online atau dalam dokumentasi ffmpeg.

Erik
sumber
2
Silakan arahkan pertanyaan ffmpeg ke video.stackexchange.com beta. Lihat deskripsi tag ffmpeg.
Ondra Žižka
34
@Ondra Bahkan stackexchange lain? Saya menjadi bingung dengan 100+ subsitus tersebut, saya tidak yakin apakah itu adalah arah positif ke arah stackexchange.
mxmlnkn
1
@mxmlnkn Saya setuju, itu membuat Anda merindukan saat-saat yang lebih sederhana ... :)
Erik
4
Aku rasa ini. StackOverflow untuk pemrograman, ini bukan pemrograman. Ada situs T&J untuk pemrosesan video, ini adalah pertanyaan tentang pemrosesan video. Apa yang tidak dimengerti?
Ondra Žižka
Baca juga deskripsi tag.
Ondra Žižka

Jawaban:

23

Saya mendapatkan ribuan peringatan ini dengan penyandian khusus. Saya menurunkan video 1080p menjadi 480p. Pada titik edit, di mana ada beberapa video yang cerdik karena cacat pada laserdisc sumber, pesan-pesan ini mulai muncul dan kemudian muncul untuk, saya pikir, setiap frame sesudahnya. Mereka terus dan terus, seperti kutipan singkat ini:

Past duration 0.901115 too large=  535031kB time=00:54:15.06 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 31 times
Past duration 0.901115 too large=  535031kB time=00:54:15.62 bitrate=1346.3kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 34 times
Past duration 0.901115 too large=  535031kB time=00:54:16.21 bitrate=1346.0kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 36 times
Past duration 0.901115 too large=  535338kB time=00:54:16.83 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 39 times

Doa ffmpeg asli adalah ini:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv

Mengikuti saran di sini saya pertama kali menambahkan -framerate 60000/1001 ke input. Itu tidak memperbaiki apa pun. Saya mempertahankan -framerate dan menambahkan -r 60000/1001 ke output. Itu masih tidak meningkatkan apa pun. Mempertahankan keduanya akhirnya saya tambahkan -async 1 -vsync 1. Hal ini mengakibatkan saya menerima satu peringatan, dan hanya itu. Doa itu adalah:

ffmpeg -i input.mp4 -framerate 60000/1001 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv -r 60000/1001 -async 1 -vsync 1

Satu-satunya perbedaan yang saya temukan dalam dump terperinci dari MediaInfo adalah penghapusan baris ini yang ditemukan dalam doa asli tetapi tidak pada yang kedua:

Delay relative to video                  : -33ms

Namun, saya memeriksa sinkronisasi A / V di dekat bagian awal file dan di dekat bagian akhir, dan tidak ada perbedaan yang terlihat dalam sinkronisasi antara kedua file. Waktu berlari mereka juga sama, tetapi itu hanya diukur ke detik terdekat, di VLC. Jadi saya memeriksa jumlah frame menggunakan ffmpeg seperti:

ffmpeg -i output.mkv -map 0:v:0 -c copy -f null -

dan mencari "frame = #" di dekat akhir output.

Ternyata sumber video panjangnya 375226 frame, doa asli menghasilkan 375195 frame, dan doa kedua menghasilkan 375200. Jadi doa kedua, dengan pesan peringatan yang jauh lebih sedikit juga turun 5 frame lebih sedikit.

Pengujian selanjutnya menunjukkan bahwa -framerate dan -r tidak perlu, dan hanya menggunakan dua flag sinkronisasi sudah cukup. Ini menghasilkan hasil yang identik dengan doa kedua di atas, jadi doa ketiga dan paling sederhana yang saya temukan untuk menyelesaikan masalah adalah ini:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv -async 1 -vsync 1

Dan file lain kemudian menghasilkan banyak peringatan ini bahkan dengan flag sinkronisasi, tetapi menambahkan kembali flag rate "memperbaiki" itu (hanya menghasilkan dua bukannya ribuan peringatan). Jadi kadang-kadang doa kedua bekerja ketika yang ketiga tidak. Untuk tujuan langsung saya, saya akan menyelesaikan doa kedua dan berharap itu memperbaiki sebagian besar masalah ini.

Ini semua dengan ffmpeg versi 4.0.

larry
sumber
2
Terima kasih untuk ini! Setelah berhari-hari mengalami masalah, -async 1 -vsync 1perbaiki untuk saya.
Offek
1
Terima kasih untuk analisis ini @larryy sangat membantu
deepelement
90

Salah satu pengelola untuk proyek DVDStyler di SourceForge mengatakan ini tentang hal itu:

Versi FFMpeg setelah 15 Januari 2015 sering menampilkan peringatan ini. Ini telah ditambahkan untuk memperingatkan tentang kemungkinan distorsi kontrol laju, jika tidak maka tidak akan menimbulkan kerugian.

Josh Davis
sumber
'tingkat kontrol distorsi' terkait dengan pengkodean (terutama video) dan tidak ada hubungannya dengan peringatan ini, yaitu tentang apakah stempel waktu keluaran berbeda terlalu banyak (relatif) dibandingkan dengan stempel waktu masukan
Gyan
Beberapa kali pertama saya mendapat peringatan saya menghentikan konversi, tetapi saran ini membuat saya membiarkannya berjalan dan peringatan berhenti setelah beberapa saat dan konversi selesai dengan sukses. Terima kasih.
IRTFM
58

Pesan peringatan ini muncul ketika mencoba untuk menyandikan sumber frame rate tinggi ke output frame rate rendah, yang berarti frame harus dijatuhkan.


Saya mengalami kesalahan ini karena saya ingin mengonversi serangkaian gambar ke video:

ffmpeg -i %05d.png -r 24 -c:v libx264 -crf 5 out.mkv

Masalahnya tampaknya, bahwa jika tidak ada frame rate yang diberikan untuk input, maka frame rate 25 fps diasumsikan:

Input #0, image2, from 'frames/%04d.bmp':
  Duration: 00:00:15.96, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: bmp, bgra, 920x650, 25 fps, 25 tbr, 25 tbn, 25 tbc

Ini juga dapat dilihat pada jumlah total frame yang dikodekan. Saya memiliki 400 gambar, tetapi perintah di atas hanya menyandikan 384:

frame=  384 fps= 68 q=-1.0 Lsize=   10931kB time=00:00:15.91 bitrate=5626.1kbits/s dup=0 drop=15    
video:10928kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.033807%

Pesan kesalahan menghilang dengan mengatur laju bingkai input sebagai gantinya jika frame rate output. Frame rate output kemudian akan secara otomatis dipilih sebagai input. Selain itu dalam versi ffmpeg baru Anda harus hati-hati, karena bila menggunakan gambar PNG dengan -ipilihan atau lebih tepatnya image2atau v4l2format masukan, Anda harus menggunakan -frameratebukan -r, lihat dokumentasi untuk -rpilihan .

ffmpeg -framerate 24 -i %05d.png -c:v libx264 -crf 5 out.mkv

Dimungkinkan juga untuk menentukan frame rate dari input dan output secara terpisah:

ffmpeg -framerate 25 -i %05d.png -r 10 -c:v libx264 -crf 5 out.mkv

Dalam hal ini hanya 161/400 frame yang akan dikodekan. Sementara bingkai lainnya akan dijatuhkan. Juga pesan kesalahan hilang, saya kira untuk tidak memperlambat ffmpeg dengan mengirim spam ke stdout, lihat:

mxmlnkn
sumber
3
"Karena hanya ketika menggunakan gambar PNG dengan opsi -i, Anda harus menggunakan -frame bukan -r" - ini menyelesaikan masalah saya sepenuhnya, terima kasih!
Anonim
1
Dalam mencoba mengkonversi wmv ke mp4, menggunakan -rbekerja di mana menggunakan -frameratetidak.
1934286
+1 dan saya sarankan untuk memindahkan "ringkasan" Anda di bagian atas. Terlebih lagi, karena ini memecahkan kasus saya mengkonversi gambar ke video dan mencoba untuk meningkatkan framerate output dan mempercepat output juga. Saya mulai dari ini ffmpeg -pattern_type glob -i '*.jpg' -filter:v "setpts=0.25*PTS" -r 50 "$( date "+%Y-%m-%d_%H%M%S")-timelapse-x4-50fps.mp4"ke ini tanpa peringatan lagi ffmpeg -framerate 50 -pattern_type glob -i '*.jpg' -filter:v "setpts=0.25*PTS" -r 50 "$( date "+%Y-%m-%d_%H%M%S")-timelapse-x4-50fps.mp4"(perhatikan -framerate 50masukan yang ditambahkan)
el-teedee
49

Melihat kode sumber tampaknya perbedaan antara waktu presentasi (pts) dalam aliran input berbeda dari yang ada di aliran output dengan lebih dari batas tetap yang ditetapkan ke 0,6.

Cuplikan dari sumber:

    delta0 = sync_ipts - ost->sync_opts;
    delta  = delta0 + duration;

...

        if (delta0 < 0 &&
        delta > 0 &&
        format_video_sync != VSYNC_PASSTHROUGH &&
        format_video_sync != VSYNC_DROP) {
        double cor = FFMIN(-delta0, duration);
        if (delta0 < -0.6) {
            av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
        } else
            av_log(NULL, AV_LOG_DEBUG, "Cliping frame in rate conversion by %f\n", -delta0);
        sync_ipts += cor;
        duration -= cor;
        delta0 += cor;
    }

Ini hanya sekilas, jadi silakan menggali lebih dalam.

Erik
sumber
Apakah ada yang bisa kita lakukan untuk "memperbaiki" masalah ini, atau secara eksplisit mengatur output pts?
Baodad
1
Saya tidak ingat detail seputar masalah ini, tetapi jika dengan "memperbaiki" yang Anda maksud adalah menghilangkan peringatan tersebut maka berdasarkan pada kode di atas Anda bisa melihat ke dalam opsi format_video_sync = VSYNC_DROPatau format_video_sync = VSYNC_PASSTHROUGHdan melihat apakah salah satu dari mereka layak dalam kasus penggunaan Anda.
Erik
Terima kasih. Saya menemukan pengaturan frame rate secara eksplisit menggunakan -rsaklar "memperbaiki" peringatan ini.
Baodad
1
Hanya sesuatu dari pengalaman pribadi: Saya mengalami masalah spam pesan "durasi lama" dan memperbaikinya dengan memaksa laju frame input dengan -r 25, tetapi kemudian saya mulai mendapatkan audio yang sangat tidak sinkron. Menghapus opsi -r dan menggunakan "-async 1 -vsync 1" untuk mencegah desync audio telah mencegah masalah audio, tetapi spam "durasi masa lalu" tampaknya juga hilang.
Jason Lang
Di v 4.1 dan yang lebih baru, level log telah ditingkatkan, sehingga tidak akan muncul di level log default.
Gyan
1

Perintah sebenarnya harus:

ffmpeg -loglevel quiet -i input_file.xyz ...

Tidak ada awalan "-" ke parameter "quiet", karena ini bukan opsi, melainkan nilai untuk opsi "-loglevel".

Gordon McCrae
sumber