การบีบอัดวิดีโอสตรีมที่รวดเร็วและไม่สูญเสีย


14

ฉันมีวิดีโอที่มาจากกล้องนิ่ง ทั้งความละเอียดและ FPS ค่อนข้างสูง ข้อมูลที่ฉันได้รับอยู่ในรูปแบบไบเออร์และใช้ 10 บิตต่อพิกเซล เนื่องจากไม่มีชนิดข้อมูล 10 บิตบนแพลตฟอร์มของฉันข้อมูลต้นฉบับจะถูกเก็บไว้ในหน่วยความจำโดยใช้คำ 16 บิต ฉันต้องการใช้การบีบอัดข้อมูลแบบไม่สูญเสียข้อมูลบางอย่างก่อนส่งผ่านเครือข่าย

  • กล้องไม่เคลื่อนไหวดังนั้นส่วนใหญ่ของเฟรมที่ต่อเนื่องกันเกือบจะเหมือนกัน - แต่ก็ยังไม่สมบูรณ์เนื่องจากเสียงที่หลีกเลี่ยงไม่ได้ (denoising ไม่ใช่ตัวเลือกเนื่องจากควรจะสูญเสียและไม่ควร "เสีย" แม้แต่เสียง )
  • เนื่องจาก FPS สูงแม้แต่ชิ้นส่วนที่เปลี่ยนจึงไม่เปลี่ยนแปลงมากนักระหว่างเฟรมต่อเนื่องสองเฟรม
  • อย่างไรก็ตามดูเหมือนว่ากล้องจะสั่นเล็กน้อย น้อยมาก แต่ถึงกระนั้นแม้กระทั่งวัตถุที่อยู่กับที่ก็ยังไม่สมบูรณ์ในพื้นที่ภาพ
  • การบีบอัดต้องทำได้อย่างรวดเร็วดังนั้นฉันจึงไม่สามารถรวบรวมเฟรมจำนวนมากและบีบอัดพวกมันทั้งหมดเข้าด้วยกัน แต่ฉันสามารถมองย้อนกลับไป 1 เฟรมและใช้เป็นข้อมูลอ้างอิงได้

ความคิดแรกของฉันคือการบีบอัดข้อมูลเพื่อให้บิตที่ซ้ำซ้อน 6 บิตเหล่านั้นไม่สูญเปล่าไปทุกคำ อย่างไรก็ตามฉันคิดว่าถ้าฉันใช้การเข้ารหัสเอนโทรปี (เช่น Huffman เป็นต้น) ความซ้ำซ้อนนั้นจะถูกนำมาพิจารณาโดยอัตโนมัติดังนั้นจึงไม่จำเป็นต้องมีการบรรจุเพิ่มเติม ดังนั้นฉันทำต่อไปนี้:

  • ใช้ความแตกต่างแบบไบนารีระหว่างสองเฟรมที่ต่อเนื่องกัน ช่วงข้อมูลดั้งเดิมคือ 0 ~ 1023 (เช่น 10 บิตที่ไม่ได้ลงชื่อ) ข้อมูลที่แตกต่างจะถูกเซ็นชื่อและช่วงจะเพิ่มเป็น -1023 ~ 1023 แต่การเปลี่ยนแปลงของข้อมูล (หรือคำศัพท์ทางคณิตศาสตร์ที่ถูกต้อง) กลายเป็นน้อยกว่าข้อมูลต้นฉบับจริง ๆ แล้วค่าส่วนใหญ่ไม่น่าประหลาดใจใกล้กับศูนย์ .
  • การประยุกต์ใช้การเข้ารหัสข้าวเพื่อความแตกต่าง จากสิ่งที่ฉันเข้าใจดูเหมือนว่าเป็นทางเลือกที่ดีสำหรับชุดข้อมูลที่มีค่าตัวเลขเล็ก ๆ เป็นส่วนใหญ่

สิ่งนี้ทำให้ฉันลดขนาดลงประมาณ 60% สำหรับ 1280x720 เฟรมและระบบทดสอบของฉัน (Linux ใน VirtualBox บนแกนเดียว) สามารถทำการบีบอัดประมาณ 40 ต่อวินาที (โดยไม่ต้องปรับให้เหมาะสมมากนัก) ไม่ใช่ว่ายอดเยี่ยม แต่ก็สมเหตุสมผลฉันเดา (หรือมันคืออะไร)

มีวิธีที่ดีกว่านี้ไหม? ข้อผิดพลาดทั่วไปที่ฉันทำ มีขั้นตอนทั่วไปที่ฉันพลาดไปไหม อาจใช้เฟรมความละเอียดที่สูงกว่าในภายหลัง - ฉันควรคาดหวังอัตราการบีบอัดที่ดีขึ้นสำหรับขนาดเฟรมที่ใหญ่ขึ้นหรือไม่

UPD .:

  • ฉันใช้ห้องสมุดนี้เพื่อเข้ารหัสข้าว ห้องสมุดช้ามาก (ผู้เขียนเองอธิบายว่ามันเป็นสิ่งที่เรียนรู้มากกว่าการใช้งานจริง) ตัวอย่างเช่นมันอ่านและเขียนบิตแบบหนึ่งต่อหนึ่งในลูปซึ่งฆ่าประสิทธิภาพการทำงาน ตอนแรกมันให้ฉันแค่ ~ 20 FPS หลังจากการเพิ่มประสิทธิภาพพื้นฐานบางอย่างมันกลายเป็น 40 FPS (ตามที่รายงานไว้ข้างต้น) หลังจากนั้นฉันก็ปรับมันให้เหมาะสมมากขึ้นแล้วก็กลายเป็น 80 นั่นคือในแกน i7 ที่เดียว
  • สำหรับ vectorization แต่น่าเสียดายที่ฉันไม่สามารถคิดวิธีการ vectorize รหัสข้าว (ไม่รู้ด้วยซ้ำว่าเป็นไปได้ทั้งหมด - ไม่สามารถหาข้อมูลใด ๆ ในรหัสข้าวสิ่งที่ฉันสามารถหาได้เกี่ยวกับรหัส Huffman แสดงให้เห็นว่า มันเป็นลำดับและไม่สามารถ vectorized ได้อย่างมีประสิทธิภาพซึ่งอาจใช้กับรหัสข้าวเช่นเดียวกับรหัสความยาวผันแปรอื่น ๆ )
  • ฉันยังลองใช้วิธีที่แตกต่างอย่างสิ้นเชิง: แยกข้อมูลออกเป็นชิ้นเล็ก ๆ (เช่น 64 พิกเซลต่อชิ้น) และใช้การปราบปรามแบบศูนย์อย่างง่าย. เราพบจำนวนมากที่สุดในบล็อกเขียนจำนวนบิตที่ต้องการเพื่อแสดงถึงจุดเริ่มต้นของบล็อก (4 บิตเพิ่มเติมจำเป็นสำหรับสิ่งนั้นในกรณีของฉัน) จากนั้นลดจำนวนทั้งหมดในบล็อกเป็นจำนวนเดียวกัน เกร็ด ฉันคาดว่าอัตราการบีบอัดจะไม่ดี แต่หากชิ้นส่วนมีขนาดเล็กส่วนใหญ่จะไม่มีสัญญาณรบกวนดังนั้นความแตกต่างแบบไบนารีของพวกเขาสามารถลดลงได้เป็น 4 ~ 6 บิตต่อมูลค่าและในความเป็นจริงเท่านั้น แย่กว่าโค้ดข้าวประมาณ 5% ในขณะที่เร็วกว่าประมาณสองเท่า (เช่น 160 FPS สำหรับกรณีของฉัน) ฉันลองใช้การทำให้เป็นเวกเตอร์แล้ว แต่ฉันก็ชอบที่ vectorization ด้วยเหตุนี้อาจเป็นเพราะฉันสามารถทำได้เพียงประมาณ 1.8 เท่าของการเร่งความเร็วต่อไป

เนื่องจากตัวเลขติดลบไม่มีศูนย์นำฉันจึงใช้การเข้ารหัสซิกแซกหลังจากความแตกต่างแบบไบนารีและก่อนการระงับข้าว / ศูนย์


คุณสามารถใช้ตัวแปลงสัญญาณมาตรฐานเช่นh264ซึ่งรองรับโหมด 10 บิต "การตั้งค่า -crf หรือ -qp ถึง 0 บังคับให้ x264 ในโหมด lossless การตั้งค่า -preset จะส่งผลต่ออัตราส่วนความเร็ว / ขนาดเท่านั้น" (แต่ฉันไม่รู้ว่ามันจะจัดการประสิทธิภาพแบบเรียลไทม์)
CodesInChaos

@CodesInChaos มันจะทำอะไรได้มากแค่สองเฟรม?
Headcrab

บางทีที่สำคัญยิ่งกว่า - ตัวแปลงสัญญาณมาตรฐานสามารถเข้ารหัสภาพของไบเออร์ได้หรือไม่? หากฉันไม่ผิดพลาดการแปลงไบเออร์เป็น RGB เกี่ยวข้องกับการแก้ไขดังนั้นจึงไม่สามารถย้อนกลับได้
Headcrab

คำตอบ:


4

คุณได้รับการทำนายทางโลก แต่ไม่มีเชิงอวกาศ เพื่อการบีบอัดที่ดีกว่าด้วยต้นทุนความเร็วคุณควรใช้พิกเซลด้านบนและด้านซ้ายของพิกเซลปัจจุบันในเฟรมปัจจุบันเป็นตัวทำนายและพิกเซลที่ตำแหน่งเดียวกันในเฟรมก่อนหน้า เหตุผลที่ค้นหาเฉพาะและซ้ายเท่านั้นเหมือนกับเหตุผลในการดูที่เฟรมก่อนหน้าเท่านั้น คุณต้องการพึ่งข้อมูลที่คุณถอดรหัสไปแล้วและ จำกัด ว่าคุณต้องเก็บข้อมูลไว้มากเพียงใด

รหัสข้าวอาจเป็นการแลกเปลี่ยนที่ดีระหว่างประสิทธิภาพและความเร็ว แต่รหัส Huffman แบบคงที่ (คำนวณโดยคุณกับตัวอย่างของข้อมูลวิดีโอ) อาจมีประสิทธิภาพและรวดเร็วกว่า

สำหรับความเร็วในการตรวจสอบให้แน่ใจว่ารหัสของคุณจะได้รับการvectorized - ทั้งโดยใช้ธงคอมไพเลอร์ที่เหมาะสมและรูปแบบรหัสที่จะอนุญาตให้คอมไพเลอร์อัตโนมัติ vectorize หรือโดยมือเขียนรหัสเพื่อใช้เวกเตอร์intrinsicsหรือประกอบ

ในที่สุดความเป็นไปได้ลดลงถึง 8 บิตต่อพิกเซลหรือไม่ เห็นได้ชัดว่าการออกจากขอบเขตของ "lossless" แต่ไม่เพียง แต่จะลดขนาดของเอาต์พุตที่ถูกบีบอัดของคุณเท่านั้นมันยังมีรหัส vectorized ซึ่งอาจเพิ่มปริมาณงานของคุณได้มากถึง 2x


ฉันเดาว่าการลด 10bpp เป็น 8 นั้นเป็นไปไม่ได้ แต่มันเป็นไปได้ที่จะเก็บ deltas ในบิตที่น้อยลงในแบบเดียวกับที่ UTF-8 ใช้ 1 หรือ 2 ไบต์บางครั้งเพื่อเก็บอักขระ ถ้าเดลต้าเกือบ 0 ตลอดเวลามันจะค่อนข้างยากที่จะเห็นการเปลี่ยนแปลงทั้ง 10 บิตและคุ้มค่ากับความพยายามในการกำหนด 1 หรือ 2 ไบต์เพื่อจัดเก็บ
gbjbaanb

@gbjbaanb นั่นคือสิ่งที่รหัสข้าวสำเร็จ เดลต้าส่วนใหญ่จะมีขนาดเล็กและใช้เพียงไม่กี่บิต
ฮอบส์

@ ฮอบส์โดย "การทำนายเชิงพื้นที่" คุณหมายถึงบางสิ่งบางอย่างเช่นการแทนที่ค่าพิกเซลx5ด้วยความแตกต่าง(x5 - x4)หรือไม่?
Headcrab

@Headcrab - วิธีที่ฉันเคยเห็นมาก่อนคือการใช้ค่ามัธยฐานของพิกเซลก่อนหน้าและพิกเซลด้านบนและซ้ายในเฟรมปัจจุบัน
จูลส์

@Jules หากพิกเซลถูกแทนที่ด้วยค่ามัธยฐานของพิกเซลล้อมรอบบางประเภทมันเป็นไปได้หรือไม่ที่จะคืนค่าดั้งเดิม
Headcrab

0

คุณอาจได้รับบริการที่ดีที่สุดโดยใช้การบีบอัดและคลายการบีบอัดที่มีอยู่แล้ว การใช้งานที่มีอยู่ของคุณดูเหมือนจะคล้ายกับตัวแปลงสัญญาณHuffYUVดังนั้นคุณควรลองใช้ดูว่ามันทำงานได้ดีพอสำหรับคุณหรือไม่


libx264 "preset เร็วมาก" ทำหน้าที่ฉันค่อนข้างดีในอดีต FWIW ...
rogerdpack

@rogerdpack - เป็นที่น่าสังเกตว่าการตั้งค่าของ libx264 สำหรับการเข้ารหัสแบบไม่สูญเสียข้อมูลในผลลัพธ์ที่ไม่สอดคล้องกับมาตรฐาน H.264 และทำลายผู้เล่นบางคน แต่มันอาจมีประโยชน์สำหรับแอปพลิเคชันของ OP อย่างน้อย
จูลส์

คุณมีลิงค์ที่น่าสนใจหรือไม่? รายงานข้อผิดพลาด? นอกจากนี้ยังทราบว่าวิดีโอที่เข้ารหัสด้วย HuffyYUV อาจจะไม่ได้เป็น "ผู้เล่นเดียวที่เป็นมิตร" อย่างใดอย่างหนึ่งผมคิด :)
rogerdpack
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.