4.15. Çerçeve Arabellekleri¶
Kamera sensörü başlatıldıktan sonra, uygulama hazır olsun ya da olmasın, her çerçeve periyodunda bir yeni çerçeve olmak üzere kendi çerçeve hızında sürekli olarak çerçeveler yayar. Her çerçevenin RAM’de inebileceği bir yere ihtiyacı vardır, aksi takdirde kaybedilir. Çerçeve arabelleği havuzu, bu çerçevelerin DMA’dan ayrıldıktan sonra ve kullanıcı kodu tarafından işlenmeden önce barındığı yerdir ve kameranın bu havuzda tuttuğu çerçeve arabelleği sayısı, DMA ile uygulamanın bunları nasıl paylaştığını kontrol eder. Bu seçim framebuffers() aracılığıyla sunulur ve arabellek sayısına göre seçilen dört mod mevcuttur.
4.15.1. Tekli arabellek (count = 1)¶
RAM’de tek bir çerçeve arabelleği. DMA onu doldurur; uygulama ondan okur; aynı arabellek her ikisi için de gerekli olduğundan, snapshot() çağrısının bir sonrakisi, uygulama arabelleği serbest bırakana kadar başlayamaz.
Kamera ve uygulama kilitli adımlarla çalışır. DMA’nın uygulamanın bitmesini beklemesi gerekir ve uygulamanın da DMA’nın bitmesini beklemesi gerekir; bu da elde edilebilecek çerçeve hızının en iyi ihtimalle sensörün çerçeve hızının yarısı olması anlamına gelir; sensörün yaydığı çerçevelerin her ikinciisi arabellek meşgulken gelir ve kaybedilir.
Bu mod RAM açısından en küçük, iş hacmi açısından ise en yavaş olanıdır. Yalnızca RAM ikinci bir arabellek ayırmaya yetmeyecek kadar darken kullanın.
4.15.2. İkili arabellek (count = 2)¶
RAM’de iki çerçeve arabelleği: DMA’nın doldurduğu bir arka arabellek ve uygulamanın okuduğu bir ön arabellek. Uygulama ön arabelleği bitirdiğinde iki rol yer değiştirir ve uygulama az önce doldurulan arabellekten okurken DMA yeni serbest bırakılan arabelleği doldurmaya başlar.
Uygulama her çerçeveyi bir kamera çerçeve periyodundan daha kısa sürede işlediği sürece, uygulama sensörün tam çerçeve hızını görür; uygulama tekrar snapshot() çağırdığında DMA’nın bir sonraki çerçevesi zaten arka arabellekte beklemektedir. Ancak işleme süresi bir çerçeve periyodunu aştığı anda hız yarıya iner: kamera, uygulamanın bir çerçeveyi işlemesi için harcadığı sürede iki çerçeve üretir ve bu ikisinden yalnızca ikincisi teslim edilir.
Bu noktanın ötesinde hız, işleme süresiyle birlikte düzgün bir şekilde bozulur. DMA, uygulama hâlâ ön arabellek üzerinde çalışırken yeni bir arka arabellek çerçevesini her bitirdiğinde, yeni çerçeve atılmak yerine önceki yakalamanın üzerine yerinde yazılır. Uygulama, bir sonraki snapshot() çağrısında her zaman kameranın ürettiği en son çerçeveyi alır ve elde edilebilecek uygulama hızı, işleme süresinin tersi olur.
4.15.3. Üçlü arabellek (count = 3)¶
RAM’de üç çerçeve arabelleği: DMA’nın döngüsel olarak kullandığı iki arka arabellek ve uygulamanın o anda üzerinde çalıştığı bir ön arabellek. Bu, yeterince RAM mevcut olduğunda OpenMV Cam’in seçtiği varsayılan moddur; yeterli RAM olmadığında ise otomatik olarak ikili veya tekli arabelleğe geri döner.
Üçüncü arabellek, kamera çerçeve hızını uygulama çerçeve hızından tamamen ayırır. DMA’nın her zaman yazacağı bir arabelleği vardır; uygulamanın her zaman okuyacağı bir arabelleği vardır; her snapshot() çağrısında hazır olan en son arka arabellek yeni ön arabellek olur ve önceki ön arabellek DMA için serbest bırakılır. Uygulamanın çerçeve hızı, her çerçeveyi işlemesi için gerçekten harcanan süreyle eşleşir; ikili arabelleğin işleme süresi bir çerçeve periyodunu az da olsa aştığında düştüğü 1/2 adımı olmadan.
4.15.4. Video FIFO (count = 4 veya daha fazla)¶
RAM’de dört veya daha fazla çerçeve arabelleği, art arda yakalanan çerçevelerden oluşan bir halka olarak düzenlenir. Kameranın teslim ettiği her çerçeve FIFO’ya kuyruğa alınır ve snapshot() en son çerçeve yerine kuyruktaki en eski çerçeveyi döndürür. Uygulama, yakalanan çerçeveler arasında yakalama sırasına göre, her biri için gerçekten harcayabileceği sürede ilerler.
Bu mod, her çerçevenin önemli olduğu ve kısa işleme duraklamalarının beklendiği durumlarda doğru seçimdir: depolama yığını bir silme işlemi sırasında onlarca milisaniye boyunca bloke olabilecek bir SD karta video yazma, kısa süreliğine okumayı durduran bir ana bilgisayara USB üzerinden akış sağlama veya hızlı bir olayın kısa bir patlamasını kodda incelemek üzere arabelleğe alma.
FIFO’nun, uygulama onu boşaltmadan önce dolması durumunu iki politika ele alır.
Eski çerçeveleri at (varsayılan). FIFO dolduğunda, etkin olan dışındaki tüm kuyruğa alınmış çerçeveler atılır; böylece bir sonraki
snapshot()eski bir çerçeve yerine güncel bir çerçeve döndürür. DMA bu süre boyunca yakalamaya devam eder, dolayısıyla uygulama bir duraklamadan sonra her zaman taze veri görür. Yakalanan akışı güncel tutmanın amaç olduğu durumlarda (video kaydı, canlı akış) doğru politika budur.Taşmada yakalamayı durdur.
CSIyapıcısınafflush=Falsegeçirin; DMA, FIFO dolu olduğunda onu doldurmayı durdurur ve kuyruğa alınmış çerçeveleri bozulmadan bırakır.snapshot(), uygulama bunları boşaltana kadar çerçeveleri yakalama sırasına göre döndürmeye devam eder, ardından DMA yeniden başlar. Kısa bir patlamanın her çerçevesini korumanın amaç olduğu durumlarda (hızlı hareketi daha sonra kodda çerçeve çerçeve incelemek üzere yakalama) doğru politika budur.
Tam API için csi.CSI.framebuffers() bölümüne bakın.
4.15.5. Tetiklemeli mod¶
Yukarıdaki sürekli çalışan modlara bir alternatif, sensörün yalnızca snapshot() istediğinde bir çerçeve yaydığı tetiklemeli yakalamadır. Kamera anlık görüntüler arasında boşta bekler ve uygulama her çağırdığında yeni bir pozlama başlatır.
Bedeli iş hacmidir: tetiklemeli bir yakalama bir öncekiyle örtüşemez, dolayısıyla elde edilebilecek maksimum çerçeve hızı sensörün normal hızının yarısıdır. Yararı ise pozlama zamanlamasıdır. Anlık görüntü, pozlamanın tam olarak ne zaman başlayacağını kontrol eder; bu da pozlamanın bir strobe flaşı, bir konveyör-konum sensörü, bir GPIO hattındaki bir darbe gibi harici bir olayla hizalanması gerektiğinde bir uygulamanın istediği şeydir; serbest çalışan sensörün yuvarlanan çerçevesinin uygulama okumaya hazır olduğunda denk geldiği yere düşmesi yerine.
Tetiklemeli mod sensöre özgüdür. Desteklenen sensörlerde csi0.ioctl(csi.IOCTL_SET_TRIGGERED_MODE, True) çağrılarak etkinleştirilir ve False geçirilerek devre dışı bırakılır.