Anahtar kareleri DASH için FFmpeg'de düzeltmenin doğru yolu nedir?


38

DASH oynatımı için bir akışı şartlandırırken, rastgele erişim noktalarının tüm akışlarda aynı kaynak akış zamanında olması gerekir. Bunu yapmanın genel yolu, sabit bir kare hızını ve sabit GOP uzunluğunu (yani her N karede bir anahtar kare) zorlamaktır.

FFmpeg'de sabit kare hızı kolaydır (-r NUMBER).

Ancak sabit anahtar kare konumları (GOP uzunluğu) için, hangisinin "doğru" olduğu üç yöntem vardır? FFmpeg belgeleri bu konuda sinir bozucu bir şekilde belirsizdir.

Yöntem 1: libx264'ün argümanlarıyla uğraşmak

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

Senaryo kapatılıp kapatılmayacağına dair bir tartışma var gibi görünüyor, çünkü sahne kesimi gerçekleştiğinde "counter" anahtar karesinin yeniden başlatılıp başlatılmadığı belli değil.

Yöntem 2: sabit bir GOP boyutunun ayarlanması:

-g GOP_LEN_IN_FRAMES

Bu ne yazık ki sadece FFMPEG belgelerine geçerken belgelenmiştir ve bu nedenle bu argümanın etkisi çok açık değildir.

Yöntem 3: her N saniyede bir anahtar kare ekleyin ( Belki? ):

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

Bu edilir açıkça belgelenmiştir. Ancak, "zaman sayacı" her anahtar çerçeveden sonra yeniden başlarsa, hemen hemen net değil. Örneğin, beklenen 5 saniyelik bir scenecutGOP’da, libx264 tarafından 3 saniye enjekte edilmiş bir anahtar kare varsa, bir sonraki anahtar kare 5 saniye sonra mı yoksa 2 saniye sonra mı?

Aslında, FFmpeg belgeleri bu -gseçenekle seçenek arasında ayrım yapar, ancak yukarıdaki bu iki seçeneğin nasıl en az biraz farklı olduğu söylenemez (tabii ki -gsabit bir kare hızı gerektirecektir).

Hangisi doğru?

-force_key_framesSabit bir kare hızı gerektirmeyeceğinden, üstün olacağı görülüyordu . Ancak, bu gerektirir

  • H.264'teki GOP şartnamelerine uygundur ( eğer varsa )
  • libx264 scenecutanahtar karelerine bakılmaksızın sabit kadansta bir anahtar kare olacağını GARANTİLER .

Ayrıca-g-rffmpeg , farklı bir kodek argümanları ile yapılan çoklu işlemlerin her çözünürlükte aynı anlık kare hızını sağlayacağının garantisi olmadığı için, sabit bir kare hızına ( ) zorlamadan çalışamayacağı da anlaşılabilir . Sabit kare hızları sıkıştırma performansını düşürebilir (DASH senaryosunda ÖNEMLİ!).

Son olarak, yöntem sadece kesmek gibi görünüyor . Umarım karşı bu doğru cevap değildir umuyorum.keyint

Referanslar:

-force_key_framesYöntemi kullanan bir örnek

keyintYöntemi kullanan bir örnek

FFmpeg gelişmiş video seçenekleri bölümü

Yanıtlar:


27

TL; DR

Aşağıdakileri tavsiye ederim:

  • libx264: (ve isteğe bağlı olarak ekle )-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

burada Xdilimlerinde aralığıdır ve Nsaniyede aralığıdır. Örneğin, 30 fps videonun 2 saniyelik bir aralığı için, X= 60 ve N= 2.

Farklı çerçeve tipleri hakkında bir not

Bu konuyu doğru bir şekilde açıklamak için, öncelikle iki tip I-frame / keyframe tanımlamamız gerekir:

  • Anlık Kod Çözücü Yenileme (IDR) çerçeveleri: Bunlar, IDR çerçevesinden önceki çerçevelere erişmeden, aşağıdaki çerçevelerin bağımsız kod çözülmesini sağlar.
  • IDR olmayan kareler: Bunlar kod çözmenin çalışması için önceki bir IDR karesini gerektirir. IDR olmayan çerçeveler, GOP'ın ortasındaki sahne kesimleri için kullanılabilir (resim grubu).

Akış için ne önerilir?

Akış durumu için şunları yapmak istersiniz:

  • Tüm IDR çerçevelerinin normal konumlarda olduğundan emin olun (örn. 2, 4, 6,… saniye), böylece videonun eşit uzunlukta bölümlere ayrılabilmesini sağlayın.
  • Kodlama verimliliğini / kalitesini artırmak için sahne kesme tespitini etkinleştirin. Bu, I-çerçevelerinin IDR çerçeveleri arasına yerleştirilmesine izin verilmesi anlamına gelir. Hala sahne kesme tespiti devre dışı bırakılmış olarak çalışabilirsiniz (ve bu hala birçok rehberin bir parçasıdır), ancak bu gerekli değildir.

Parametreler ne işe yarar?

Enkoderi yapılandırmak için, anahtar kare parametrelerinin ne yaptığını anlamamız gerekir. Bazı testler yaptım ve üç kodlayıcılar için aşağıdakileri keşfetti libx264, libx265ve libvpx-vp9FFmpeg içinde:

  • libx264:

    • -g anahtar kare aralığını ayarlar.
    • -keyint_min minimum anahtar kare aralığını ayarlar.
    • -x264-params "keyint=x:min-keyint=y"aynıdır -g x -keyint_min y.
    • Not: Her ikisini de aynı değere ayarlarken, minimum dahili olarak maksimum aralık artı yarıda , x264kodda görüldüğü gibi ayarlanır :

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

    • -g uygulanmadı.
    • -x265-params "keyint=x:min-keyint=y" Eserleri.
  • libvpx-vp9:

    • -g anahtar kare aralığını ayarlar.
    • -keyint_min minimum anahtar kare aralığını ayarlar
    • Not: FFmpeg'in nasıl çalıştığından dolayı -keyint_min, sadece aynı olduğu zaman kodlayıcıya iletilir -g. libvpxenc.cFFmpeg'deki kodda şunları bulabiliriz:

      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;
      

      Bu bir hata olabilir (veya özellik eksikliği?), Çünkü libvpxkesinlikle farklı bir değerin ayarlanmasını destekliyor kf_min_dist.

Kullanmak mı -force_key_frames?

-force_key_framesSeçenek zorla verilen aralık (ifade) ana kareler ekler. Bu, tüm kodlayıcılar için işe yarar, ancak hız kontrol mekanizması ile karışabilir. Özellikle VP9 için ciddi kalite dalgalanmaları fark ettim, bu yüzden bu durumda kullanmanızı tavsiye edemiyorum.


Teşekkür ederim! Bu harika bir geri bildirim. Tek sorum, bu harika masayı nasıl yarattığınız. Tamamen böyle bir şey kullanabilirim.
Mark Gerolimatos,

(Size doğrudan yazmanın bir yolu yok gibi görünüyor) Lütfen bu ITU-T tartışmasındaki herhangi bir başlığın bağlantısını gösterebilir misiniz? Teşekkürler!
Mark Gerolimatos,

2
Excel'de, üç işlemden elde ettiğim çıktıyı yapıştırıp ffprobe -i input.mp4 -select_streams v -show_frames -of csv -show_entries frame=pict_typehücreleri renklendirdim. Korkarım halka açık tartışmalar yok, ama o zaman bulduğum linklerden bazılarını kazıp çıkaramayacağımı göreceğim.
slhck '

Lütfen bu -force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)formu denemenizi tekrar deneyebilir misiniz ? Sadece denedim ve akışta fazladan I kareleri varken, kuralımın uyduğu görünüyordu. Bir PERL programı yorumlarda biçimlendirme kullanamadığınızdan "cevap" olarak geçecektir.
Mark Gerolimatos

İlginç. İşe yaradığını öğrenirseniz, ayrı bir "gerçek" cevaba değeceğine inanıyorum. (Stack Exchange siteleri bu tartışma tarzı cevap için pek iyi değil.) Son kontrol ettiğimde, -force_key_framesbenim için işe yaramadı ve bu yüzden bir daha hiç denemedim. Bu bir yıldan daha önceydi. Belki de bir hataydı. Yakında tekrar deneyeceğim.
00'te slhck

12

İşte dava için elli sentim.

Yöntem 1:

libx264'ün argümanlarıyla uğraşmak

-c: v libx264 -x264 seçeneği keyint = GOPSIZE: min-keyint = GOPSIZE: scenecut = -1

Yalnızca istediğiniz aralıklarda iframe üretin.

Örnek 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

Bu şekilde beklendiği gibi iframe üret:

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

Yöntem 2, amortismana tabi tutulmuştur. Ommitted.

Yöntem 3:

her N saniyede bir anahtar kare ekleyin (MAYBE):

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

Örnek 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

İfadeleri biraz farklı bir şekilde oluşturun:

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

Gördüğünüz gibi, her 2 saniyede bir iframe yerleştiriyor VE bana göre video akışı karmaşıklığı için önemli olan senaryoya (kayan kısım ile saniye) yerleştiriyor.

Üretilen dosya boyutları hemen hemen aynıdır. Yöntem 3'te daha fazla anahtar kare olsa bile, standart x264 kütüphane algoritmasından bazen daha az dosya üretmesi çok garip .

HLS akışı için çoklu bitrate dosyaları oluşturmak için, üçüncü yöntemi seçiyoruz. Parçalar arasında 2 saniye ile mükemmel bir şekilde hizalanmış, her parça başında iframe'leri var ve eski modası olan cihazları olan ve x264 yüksek profillerini oynatamayan kullanıcılar için daha iyi bir deneyim sağlayan karmaşık sahnelerde ek iframe'leri var.

Umarım birine yardımcı olur.


Fantastik, 50 kuruş için teşekkürler!
BrunoFenzl

7

Bu nedenle cevap şöyle görünüyor:

  • Metot 1'in çalıştığı doğrulanır, ancak libx264kendine özgüdür ve içindeki çok kullanışlı scenecutseçeneğin ortadan kaldırılması pahasına gelir libx264.
  • Yöntem 3, Nisan 2015'in FFMPEG sürümünden itibaren çalışır, ancak FFMPEG belgelerinin seçeneğin etkisi konusunda net olmadığı için sonuçlarınızı bu yazının alt kısmında yer alan komut dosyasıyla doğrulamanız gerekir. Çalışırsa, iki seçeneğin üstündür.
  • KULLANMAYIN Yöntem 2, -gkullanım dışı görünüyor. Ne işe yaramış görünmektedir, ne de dokümantasyonda açıkça tanımlanmış, ne yardımda bulunmuş ne de kodda kullanılmış gibi. Kod incelemesi, -gseçeneğin MPEG-2 akışları için geçerli olduğunu gösterir (PAL ve NTSC!

Ayrıca:

  • Metot 3 ile oluşturulan dosyalar, interstisyel I karelere (anahtar karelere) izin verildiğinden Metot 1'den biraz daha büyük olabilir.
  • Açıkça, her iki durumda da olsa Yöntem 3 yerleri veya sonraki frameslot de bir I çerçeve "-r" bayrak belirlesin sonra belirlenen süre. "-R" bayrağını ayarlamadaki başarısızlık sizi kaynak dosyanın insafına, muhtemelen değişken kare hızına getirir. Uyumsuz DASH geçişleri ortaya çıkabilir.
  • FFMPEG dokümantasyonundaki uyarılara rağmen, yöntem 3 diğerlerinden daha az verimli DEĞİLDİR . Aslında, testler bunun yöntem 1'den biraz daha DAHA etkili olabileceğini göstermektedir.

-force_key_framesSeçenek için komut dosyası

İşte slhck'ın ffprobe önerisinin çıktısına dayanarak I-kare kadansını doğrulamak için kullanılan kısa bir PERL programı. -force_key_framesYöntemin de işe yarayacağını ve scenecutçerçevelere izin vermenin ek faydası olduğunu doğrulamış görünüyor . FFMPEG'in bu işi nasıl yaptığını ya da akışlarımı iyi durumda olduğu için bir şekilde şansımı yattığım konusunda hiçbir fikrim yok.

Benim durumumda, beklenen frekansın 6 saniyelik GOP veya 180 karesiyle 30 kare / sn olarak kodladım. Bu programa gopsize argümanı olarak 180'i kullandım, her 180'in çoğunda bir I çerçevesi doğruladım, ancak bunu 181'e (ya da 180'in katı olmayan herhangi bir sayıya) ayarlamak şikayetçi oldu.

#!/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;
}

Sadece bir not: Bu bir Q&A sitesi olduğundan ve mesajların kronolojik olarak sıralandığı gerçekten bir tartışma forumu olmadığı için, tüm bilgileri tek bir cevaba yerleştirmek en iyisidir , böylece bir çözüm arayanların sadece bir yazıyı okuması gerekir. kim ne göndermiş, ne zaman :) Cevaplarınızı birleştirdim ve bu konuda da +1 verdim. Yana çapraz nakil izin verilmez , sana video sitesinde soruyu silmek öneririm. İnsanlar cevapları burada bulacaklar.
slhck

1
Sadece bir tane daha düşündüm (aslında FFmpeg posta listesinde büyüdü). Kullandığınızda force_key_frames, bu tür x264 bit ayırma algoritmasını bozar, bu nedenle yalnızca sabit bir anahtar kare aralığı ayarlamaktan daha kötü bir kalite verebilir.
slhck

Kutsal bok Yine de, FFMPEG'in kodek-nonspesifik bir yöntem sunması için bir neden daha, “söz konusu kodek için en iyi şeyi yapan şey” argümanı.
FFMPEG'in trac'i

@slhck: Lütfen daha fazla ayrıntı verebilir misiniz? Mayıs 2015'te posta listesi arşivlerine baktım ancak hiçbir şey bulamadım. Alt satırda "Yöntem 3" ü unutmak ve "Yöntem 1" e sadık kalmak olacaktır.
schieferstapel

3
@MarkGerolimatos: hakkında -g, "Ne işe yaramış görünmüyor, ne de kodda kullanılıyor gibi görünüyor" diyorsunuz. Kontrol ettim ve giriş gsaklanır avctx->gop_sizelibx264 marka ve bunun kullanımı: x4->params.i_keyint_max = avctx->gop_size;. Bu oluşturulan test dosyasını ffmpeg -i a-test-file.mp4 -g 37 -t 15 gtest.mp4araştırdığımda : Anahtar kareleri tam olarak alıyorum 0,37,74,111,148,185,222,259,296,333,370. Sahne değişikliği tetiklenirse GOP kısa kesilebilir ve -sc_thresholdbunun için de x264 tarafından algılanan ayar yapılabilir.
Gyan

4

Googling'im DASH'imi istediğim şekilde kodlayan bir yol bulmaya çalışırken bilgi bulma arayışımdan biraz daha bu soruları çektiğim için biraz bilgi eklemek istedim ve bulduğum bilgilerin hiçbiri tamamen doğru değildi.

Kurtulmak için ilk birkaç yanlış anlamalar:

  1. Tüm I kareleri aynı değildir. Büyük "ben" kareleri ve küçük "ben" kareleri var. Veya doğru terminoloji, IDR I-Frame'leri ve IDR-I-Frame'leri kullanmak için. IDR I kareleri (bazen "ana kareler" olarak adlandırılır) yeni bir GOP oluşturur. IDR olmayan çerçeveler olmaz. Bir sahne değişikliğinin olduğu bir GOP'ın içindekilere sahip olmak için kullanışlıdırlar.

  2. -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE← Bu düşündüğünüzü yapmaz. Bu beni anlamak için biraz zaman aldı. Kodda min-keyintsınırlı olduğu ortaya çıkıyor . Bundan daha büyük olmasına izin verilmiyor (keyint / 2) + 1. Dolayısıyla aynı değeri bu iki değişkene atamak, min-keyintkodlama sırasında yarı yarıya düşürülmekle sonuçlanır .

İşte size bir şey var: sahne kesimi gerçekten harika, özellikle de hızlı kesik videolar var. Güzel ve canlı tutar, bu yüzden devre dışı bırakmak istemem ama aynı zamanda etkin olduğu sürece sabit bir GOP boyutu alamadım. Sahne kesmeyi etkinleştirmek istedim, ancak yalnızca IDR olmayan I kareleri kullanması için. Ama işe yaramadı. 2 numaralı yanlış anlama hakkında (pek çok okumadan) anlayana kadar.

keyintİstediğim GOP boyutumu iki katına çıkarmam gerekti . Bu min-keyint, en son IDR I-Frame'den beri kare sayıldığından, sahne kesimi saptamasının GOP boyutunda IDR I-kare kullanmasını engelleyen (iç kodun yarısı kadar kesmeden) istediğim şekilde ayarlanabileceği anlamına geliyor. her zaman daha az min-keyinit.

Sonunda force_key_frameseçeneği ayarlamak çift ​​boyutu geçersiz kılar keyint. İşte işte işe yarayan:

Segmentleri 2 saniyelik parçalarda tercih ederim, bu yüzden 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>

Ffprobe kullanarak doğrulayabilirsiniz:

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

Oluşturulan CSV dosyasında her satır size söyleyecektir 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

Sonuç olarak, IDR I-Frame'leri yalnızca belirli GOPSIZEaralıklarla görmeniz gerekirken , diğer tüm I kareleri sahne kesme algılaması tarafından gerektiğinde eklenen IDR I-kareleri değildir.


Bu harikaydı! Oldukça karşı yönelimli bir aldo oldu, çabayı gösterdiğiniz için teşekkür ederim. Ve özetlemek gerekirse, "I-kareler" ve "i-kareler" tanımınızın kavramsal olduğunu (yani, libx264'te açıkça konfigüre edilemez) ve "maks * 2" nin sizin zorladığınız şekilde olduğunu mu varsayıyorum?
Mark Gerolimatos

Evet, kavramsalydı, insanlar IDR ile IDR olmayan I-kareleri arasında ayrım yapmak için "ben" vs "ben" i kullandı. Ve evet, keyinit'in istenen gop boyutuna * 2 ayarlanması, gop içindeki tüm I çerçevelerinin IDR I-çerçeveleri olmaya zorlanmasının bir yoludur. Daha sonra ffmpeg -force-key-frames, x264opts içindeki key-init'i geçersiz kılar. Temel olarak, eğer x264 kodu min-keyinit ve keyinit'i aynı değere ayarlamanıza izin verirse mümkün olacak olan sonucu elde etmenin gerçekten geriye doğru bir yoludur.
Reuben

... aynı zamanda hem sahne kesimi algılamanın açık kalmasını hem de GOP boyutunun sabitlenmesini sağlar.
Reuben,

harika işin için tekrar teşekkürler! Görünüşe göre onu etkilemenin daha az "geriye" bir yoluna ihtiyacımız var
Mark Gerolimatos

Burada rc-lookahead gerekli mi? Mbtree ve VBV'yi etkiler, ancak i-frame oluşumunu etkiler mi?
Alexander Svetkin,

0

Görünüşe göre bu sözdizimi her zaman işe yaramıyor gibi gözüküyor. VOD içeriğimizin yanı sıra canlı içerik (dosya dökümleri) ve bazen senaryo üzerinde çok fazla test yaptım ve iframe arasında bir içeri girdi oluşturmuyor:

İ50-> p50 upconvertion için sözdizimi, 2 sn gop / segment, başlangıçta IDR, gerekirse aralarında iç çerçeveler

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'in bu konuda bir yayını var. Kendi programlarını çeşitli nedenlerle kullanmaya karar verdiklerini açıklarlar; bunlardan biri, ffmpeg'in farklı iş parçacıklarında farklı x264 örnekleri çalıştırmanıza izin vermemesiydi, bunun yerine bir sonraki çıktıya geçmeden önce belirtilen iş parçacıklarını bir çıktıdaki bir kareye ayırıyordu.

Gerçek zamanlı yayın yapmıyorsanız, daha fazla lüksünüz vardır. 'Doğru' yol muhtemelen bir çözünürlükte sadece -g ile belirtilen GOP boyutunda kodlamak ve ardından aynı yerlerde anahtar kareleri zorlayan diğer çözünürlükleri kodlamaktır.

Bunu yapmak istiyorsanız, ana kare zamanlarını almak için ffprobe'yi kullanabilir ve ardından bunu bir ffmpeg komutuna dönüştürmek için bir kabuk betiği veya gerçek bir programlama dili kullanabilirsiniz.

Ancak çoğu içerik için, her 5 saniyede bir anahtar kareye ve her 5 saniyede bir iki anahtar kareye sahip olmak (biri zorunlu ve senaryodan biri olmak) arasında çok az bir fark vardır. Bu, P-kare ve B-kare boyutuna kıyasla ortalama I-kare boyutuyla ilgilidir. X264'ü tipik ayarlarla kullanıyorsanız (bunları etkilemek için her şeyi yapmanız gerektiğini düşündüğüm tek neden, x264'ün kolay içerikte bit hızını kullanmasını engellemenin kötü bir yolu olarak -qmin'i ayarlamanızdır; bu, tüm kare türlerini aynı değerle sınırlar , Sanırım) ve I-kare ortalama 46 kB ortalama boyutu, P-kare 24 kB, B-kare 17 kB (P-kare'ler kadar sık), ardından her saniyede 30 fps'de ekstra bir I-kare gibi bir sonuç alıyor. dosya boyutunda sadece% 3 artış. H264 ve h263 arasındaki fark% 3'lük bir düşüş grubundan oluşuyor olabilir, ancak bir tanesi çok önemli değil.

Diğer içerik türlerinde kare boyutları farklı olacaktır. Adil olmak gerekirse, bu zamansal karmaşıklık ile ilgilidir ve mekansal karmaşıklık ile ilgili değildir, bu nedenle zor içerikle yalnızca kolay içerik değildir. Ancak, genel olarak, akışlı video sitelerinin bit hızı sınırlaması vardır ve göreceli olarak büyük I kareleri olan içerik, ne kadar fazla anahtar kare eklenirse yapılsın yüksek kalitede kodlanacak kolay içeriktir. Atılgandır, ancak bu atık genellikle fark edilmez. En israf verici durum, muhtemelen her bir anahtar karenin tamamen aynı olduğu, bir şarkıya eşlik eden statik bir görüntü olan bir videodur.

Emin değilim, zorunlu anahtar karelerin -maxrate ve -bufsize ile ayarlanan hız sınırlayıcı ile nasıl etkileşime girdiğidir. YouTube’un bile, tutarlı bir kalite vermek için arabellek ayarlarını doğru bir şekilde yapılandırmakta sıkıntı yaşadığını düşünüyorum. Bazı siteler tarafından görülebileceği gibi sadece ortalama bit hızı ayarları kullanıyorsanız (x264'ün başlık / mov atomundaki (bir hex editörüyle? kullanıcı tarafından oluşturulan içeriği sunan ortalama bit hızı, kullanıcıları videolarının sonuna siyah ekran eklemeye teşvik eder.

Ffmpeg'in -g seçeneği veya kullandığınız diğer herhangi bir kodlayıcı seçeneği, kodlayıcıya özgü seçeneğe eşlenir. Yani '-x264-params keyint = GOPSIZE', '-g GOPSIZE' ile eşdeğerdir.

Sahne algılamanın kullanılmasıyla ilgili bir sorun, herhangi bir nedenden ötürü belirli numaraların yanında anahtar kareleri tercih etmenizdir. Her 5 saniyede bir anahtar kare belirlerseniz ve sahne algılamayı kullanırsanız ve 4.5'te bir sahne değişikliği varsa, o zaman algılanmalıdır, ancak bir sonraki anahtar kare 9.5'te olacaktır. Zaman böyle artmaya devam ederse, 40, 45, 50, 55 yerine 42.5, 47.5, 52.5, vb. Anahtar karelere sahip olabilirsiniz. Buna karşılık, 5.5'te bir sahne değişikliği varsa, o zaman 5 ve 5.5'teki bir anahtar kare bir başkası için çok erken olacak. Ffmpeg, "gelecek 30 karede sahne değişikliği olmazsa burada bir ana kare yap" seçeneğini belirtmeme izin vermiyor. C anlayan biri bu seçeneği ekleyebilir.

Değişken kare hızındaki video için, Twitch gibi canlı akış yapmadığınızda, sürekli kare hızına dönüştürmeden sahne değişikliklerini kullanabilmelisiniz. Ffmpeg'de 'select' filtresini kullanırsanız ve ifadede 'scene' sabitini kullanırsanız, hata ayıklama çıktısı (-v debug veya kodlama sırasında birkaç kez '+' tuşuna basmak) sahne değişim numarasını gösterir. Bu muhtemelen x264 tarafından kullanılan sayıdan farklıdır ve bu kadar kullanışlı değildir, ancak yine de yararlı olabilir.

O zaman prosedür, muhtemelen sadece ana kare değişiklikleri için olan bir test videosu yapmak olacaktır, ancak 2-pass kullanılıyorsa hız kontrol verileri için kullanılabilir. (Oluşturulan verinin farklı çözünürlükler ve ayarlar için hiç faydalı olup olmadığından emin değil; makroblok ağacı verileri olmayacak.) Sabit kare hızındaki videoya dönüştürün, ancak karar verirseniz kare hızını yarı yarıya düşürürken bu kekemelik çıktısını görün fps filtresini başka amaçlarla kullanmak için. İstediğiniz ana kare ve GOP ayarlarınızla x264 üzerinden çalıştırın.

Ardından, sadece bu ana kare zamanlarını orijinal değişken kare hızlı videoyla kullanın.

Çerçeveler arasında 20 saniyelik bir boşlukla tamamen delice kullanıcı tarafından oluşturulan içeriğe izin verirseniz, değişken kare hızı kodlaması için çıktıyı bölebilir, fps filtresi, bir şekilde seçme filtresi kullanabilirsiniz (belki de çok uzun bir ifade oluşturabilir. Her anahtar kare zamanında) ... veya belki de test videosunu girdi olarak kullanabilir ve eğer ffmpeg seçeneği işe yaradıysa, sadece ana karelerin kodunu çözebilir veya ana kareleri seçmek için seçim filtresini kullanabilirsiniz. Ardından doğru boyuta ölçeklendirin (bunun için bir scale2ref filtresi bile var) ve orijinal videoyu üzerine yerleştirin. Ardından, bu zorlamalı ana anahtar kareleri orijinal video ile birleştirmek için ara süzgeci kullanın. Bu, interleave filtresinin engellememesi dışında 0,001 sn'lik iki kareyle sonuçlanırsa, bu sorunu başka bir seçme filtresiyle kendiniz çözün. Serpiştirici filtre için çerçeve tamponu sınırlarıyla başa çıkmak, burada ana sorun olabilir. Bunların hepsi işe yarayabilir: daha yoğun akımı tamponlamak için bir tür filtre kullanın (beşli filtre?); giriş dosyasına birden çok kez bakın, böylece bir kereden fazla kod çözülür ve karelerin kaydedilmesi gerekmez; Ana kareler zamanında, hiç yapmadığım 'streamselect' filtresini kullanın; varsayılan davranışını değiştirerek veya en eski kareyi bir kare bırakmak yerine arabellekte çıkarmak için bir seçenek ekleyerek ara süzgeci geliştirin. Anahtar karelerin tam zamanında, hiç yapmadığım; varsayılan davranışını değiştirerek veya en eski kareyi bir kare bırakmak yerine arabellekte çıkarmak için bir seçenek ekleyerek ara süzgeci geliştirin. Anahtar karelerin tam zamanında, hiç yapmadığım; varsayılan davranışını değiştirerek veya en eski kareyi bir kare bırakmak yerine arabellekte çıkarmak için bir seçenek ekleyerek ara süzgeci geliştirin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.