एक वीडियो स्ट्रीम का तेज, दोषरहित संपीड़न


14

मेरे पास स्थिर कैमरे से आने वाला वीडियो है। संकल्प और एफपीएस दोनों काफी अधिक हैं। मुझे जो डेटा मिलता है वह बायर प्रारूप में है और प्रति पिक्सेल 10 बिट का उपयोग करता है। जैसा कि मेरे प्लेटफ़ॉर्म पर कोई 10 बिट डेटा प्रकार नहीं है, मूल डेटा 16-बिट शब्दों का उपयोग करके मेमोरी में संग्रहीत किया जाता है। मैं नेटवर्क पर संचारित करने से पहले डेटा के कुछ प्रकार के दोषरहित संपीड़न को लागू करना चाहता हूं ।

  • कैमरा हिलता नहीं है, इसलिए लगातार फ़्रेम के बड़े हिस्से लगभग समान होते हैं - लेकिन फिर भी पूरी तरह से नहीं, अपरिहार्य शोर के कारण (निंदा करना एक विकल्प नहीं है, क्योंकि यह दोषरहित माना जाता है और शोर को "खोना" भी नहीं चाहिए) )।
  • उच्च एफपीएस के कारण, यहां तक ​​कि जो हिस्से बदलते हैं, वे किसी भी दो लगातार फ्रेम के बीच ज्यादा नहीं बदलते हैं।
  • हालाँकि, ऐसा लग रहा है कि कैमरा भी थोड़ा हिलता है। बहुत कम, लेकिन फिर भी, यहां तक ​​कि स्थिर ऑब्जेक्ट पूरी तरह से छवि स्थान में नहीं हैं।
  • संपीड़न को मक्खी पर किया जाना है, इसलिए मैं बहुत सारे फ़्रेमों को इकट्ठा नहीं कर सकता और उन सभी को एक साथ संपीड़ित कर सकता हूं, लेकिन मैं 1 फ्रेम को वापस देख सकता हूं और इसे संदर्भ के रूप में उपयोग कर सकता हूं।

उपरोक्त के आधार पर, मेरा पहला विचार डेटा को बिट-पैक करना था, ताकि हर शब्द पर उन 6 अनावश्यक बिट्स बर्बाद न हों। हालाँकि, मैंने सोचा कि अगर मैं कुछ एन्ट्रापी कोडिंग (जैसे हफ़मैन आदि) का उपयोग करता हूं, तो अतिरेक को स्वचालित रूप से ध्यान में रखा जाएगा, इसलिए कोई अतिरिक्त पैकिंग आवश्यक नहीं है। इसलिए मैंने निम्नलिखित कार्य किए हैं:

  • दो लगातार फ्रेम के बीच द्विआधारी अंतर लिया। मूल डेटा सीमा 0 ~ 1023 (जैसे अहस्ताक्षरित 10 बिट्स) थी। अंतर डेटा पर हस्ताक्षर किए जाते हैं और सीमा -1023 ~ 1023 तक बढ़ जाती है, लेकिन डेटा भिन्नता (या क्या सही गणितीय शब्द है) मूल डेटा की तुलना में बहुत कम हो जाता है, वास्तव में, अधिकांश मूल्य आश्चर्यजनक रूप से शून्य के करीब नहीं हैं। ।
  • लागू चावल कोडिंग अंतर के लिए। जो मैं समझता हूं, वह ज्यादातर छोटे संख्यात्मक मूल्यों के डेटा सेट के लिए एक अच्छा विकल्प है।

यह मुझे 1280x720 फ्रेम के लिए आकार में लगभग 60% की कमी देता है, और मेरी परीक्षा प्रणाली (एक कोर में वर्चुअलबॉक्स में लिनक्स) प्रति सेकंड 40 (अधिक अनुकूलन के बिना) ऐसा कर सकता है। यह महान नहीं है, लेकिन उचित है, मुझे लगता है (या यह है?)।

क्या बेहतर तरीके हैं? मैंने जो भी सामान्य गलतियाँ की हैं? कोई भी सामान्य चरण जो मैंने याद किया? उच्च रिज़ॉल्यूशन फ़्रेम का उपयोग बाद में किया जा सकता है - क्या मुझे बड़े फ्रेम आकारों के लिए बेहतर संपीड़न दरों की उम्मीद करनी चाहिए?

युपीडी .:

  • मैंने इस लाइब्रेरी का इस्तेमाल राइस एन्कोडिंग के लिए किया। पुस्तकालय बहुत धीमा है (लेखक स्वयं इसे वास्तविक उपयोग के बजाय सीखने के लिए कुछ के रूप में वर्णित करता है), उदाहरण के लिए यह छोरों को एक-एक करके पढ़ता और लिखता है, जो प्रदर्शन को मारता है। प्रारंभ में इसने केवल मुझे ~ 20 एफपीएस दिया, कुछ बहुत ही बुनियादी अनुकूलन के बाद यह 40 एफपीएस बन गया (जैसा कि ऊपर बताया गया है), बाद में मैंने इसे कुछ और अनुकूलित किया, यह 80 हो गया। यह बिना वेक्टरकरण के एक एकल i7 कोर पर है।
  • वैश्वीकरण के रूप में, हालांकि, दुर्भाग्य से मैं चावल कोड को वेक्टर करने का तरीका नहीं सोच सकता (यह भी नहीं जानता कि क्या यह सब संभव है - राइस कोड पर कोई डेटा नहीं मिल सकता है, हफमैन कोड के बारे में मुझे क्या पता चलता है कि पता चलता है) यह अनुक्रमिक है और कुशलता से सदिश नहीं किया जा सकता है, जो राइस कोड के साथ-साथ अन्य चर-लंबाई कोड पर भी लागू हो सकता है)।
  • मैंने भी पूरी तरह से अलग दृष्टिकोण की कोशिश की: डेटा को छोटे टुकड़ों में विभाजित करें (जैसे 64 पिक्सेल एपलस) और सरल शून्य दमन का उपयोग करें। हम एक ब्लॉक में सबसे बड़ी संख्या पाते हैं, इसे ब्लॉक की शुरुआत में प्रतिनिधित्व करने के लिए आवश्यक बिट्स की संख्या लिखें (4 अतिरिक्त बिट्स उसके लिए आवश्यक थे, मेरे मामले में), फिर ब्लॉक में सभी संख्याओं को समान संख्या में घटाएं बिट्स। मुझे उम्मीद है कि संपीड़न दर खराब होगी, लेकिन अगर टुकड़े छोटे होते हैं, तो उनमें से कई में शोर स्पाइक्स नहीं होंगे, इसलिए उनके द्विआधारी अंतर को प्रति मूल्य 4 ~ 6 बिट्स की तरह कम किया जा सकता है, और यह वास्तव में, केवल था चावल कोड की तुलना में लगभग 5% खराब है, जबकि दो बार तेजी से (उदाहरण के लिए मेरे मामले के लिए 160 एफपीएस)। मैंने इसे वेक्टर करने की कोशिश की, लेकिन मैं वेक्टराइज़ेशन में चूसना चाहता हूं, इसलिए शायद इस वजह से मैं केवल आगे की गति के X1.8 के बारे में हासिल कर सका।

क्योंकि ऋणात्मक संख्याओं में अग्रणी शून्य नहीं होता है, मैंने द्विआधारी अंतर के बाद और चावल / शून्य दमन से पहले ज़िगज़ैग एन्कोडिंग लागू किया ।


आप h264 जैसे एक मानक कोडेक का उपयोग कर सकते हैं जो 10 बिट मोड का समर्थन करता है। "सेटिंग -crf या -qp से 0 बल x264 को दोषरहित मोड में -setet सेटिंग्स पर लागू करें, फिर बस गति / आकार अनुपात को प्रभावित करें।" (लेकिन मुझे नहीं पता कि यह वास्तविक समय के प्रदर्शन का प्रबंधन करेगा)
कोडइंचाओस

@CodesInChaos, क्या यह सिर्फ दो फ्रेम के लिए बहुत कुछ करेगा?
हेडक्रैब

शायद, इससे भी महत्वपूर्ण बात - मानक कोडेक्स भी बायर छवियों को सांकेतिक शब्दों में बदल सकते हैं? अगर मैं गलत नहीं हूं, तो बायर टू आरजीबी में रूपांतरण में प्रक्षेप शामिल है, और इसलिए अपरिवर्तनीय है।
हेडक्रैब जूल 5'16

जवाबों:


4

आपको अस्थायी भविष्यवाणी मिली है, लेकिन कोई स्थानिक नहीं है। गति की लागत पर बेहतर संपीड़न के लिए, आपको ऊपर के पिक्सेल का उपयोग करने में सक्षम होना चाहिए और वर्तमान फ्रेम में वर्तमान पिक्सेल के बाईं ओर पूर्वसूचक के रूप में, साथ ही साथ पिछले फ्रेम में उसी स्थान पर पिक्सेल का उपयोग करना चाहिए। केवल ऊपर और बाएं देखने का कारण वही है जो केवल पिछले फ्रेम को देखने का कारण है; आप केवल उन डेटा पर निर्भर रहना चाहते हैं जिन्हें आप पहले ही डिकोड कर चुके हैं, और यह सीमित करें कि आपको कितना रखना है।

दक्षता और गति के बीच चावल कोड शायद एक अच्छा ट्रेडऑफ़ है, लेकिन एक स्थिर हफ़मैन कोड (वीडियो डेटा के नमूने पर आपके द्वारा precomputed) अधिक कुशल और समान रूप से तेज़ हो सकता है।

गति के लिए, सुनिश्चित करें कि आपका कोड वेक्टरकृत हो रहा है - या तो कंपाइलर को ऑटो-वेक्टराइज़ करने की अनुमति देने के लिए सही कंपाइलर फ़्लैग और कोड पैटर्न का उपयोग करके, या वेक्टर इंट्रिंसिक्स या असेंबली का उपयोग करने के लिए कोड को हाथ से लिखकर ।

अंत में, प्रति पिक्सेल 8 बिट्स को छोड़ने की संभावना है? जाहिर है कि "दोषरहित" के दायरे को छोड़ रहा है, लेकिन यह न केवल आपके संपीड़ित उत्पादन के आकार को कम करेगा, यह वेक्टर कोड के साथ, संभवतः अपने थ्रूपुट को 2x तक बढ़ाएगा।


मुझे लगता है कि 10 बीपीपी को 8 तक कम करना संभव नहीं है, लेकिन डेल्टास को कम बिट्स में स्टोर करना संभव हो सकता है, उसी तरह जैसे कि यूटीएफ -8 एक चरित्र को स्टोर करने के लिए 1 या कभी-कभी 2 बाइट्स का उपयोग करता है। यदि डेल्टास हर समय लगभग 0 है, तो सभी 10 बिट्स को बदलना काफी दुर्लभ होगा, और इसलिए उन्हें स्टोर करने के लिए 1 या 2 बाइट्स का निर्धारण करने के प्रयास के लायक है।
gbjbaanb

@gbjbaanb कि चावल कोडिंग क्या पूरा करती है। अधिकांश डेल्टास छोटे होंगे, और इस प्रकार केवल कुछ बिट्स का उपयोग करेंगे।
हॉब्स

@ ओह, "स्थानिक भविष्यवाणी" से क्या आपको कुछ मतलब है जैसे x5अंतर के साथ पिक्सेल मूल्य को बदलना (x5 - x4)?
हेडक्रैब

@ हैडक्राब - मैंने पहले देखा हुआ एक दृष्टिकोण पिछले पिक्सेल के औसत मूल्य और ऊपर के पिक्सल का उपयोग करना और वर्तमान फ्रेम में छोड़ दिया है।
जूल्स

@ जूल्स यदि किसी पिक्सेल को आसपास के पिक्सेल के कुछ प्रकार के औसत मूल्य से बदल दिया जाता है, तो क्या इसका मूल मूल्य बहाल करना संभव है?
हेडक्राब

0

आप शायद संपीड़न और विघटन के मौजूदा कार्यान्वयन का उपयोग करके सबसे अच्छी सेवा कर रहे हैं। आपका मौजूदा कार्यान्वयन HuffYUV कोडेक के समान है , इसलिए यह देखने लायक है कि यह देखने के लिए कि क्या यह आपके लिए पर्याप्त रूप से काम करता है।


libx264 "प्रीसेट अल्ट्राफास्ट" ने मुझे काफी ऐतिहासिक रूप से FWIW परोस दिया है ...
rogerdpack

@rogerdpack - यह ध्यान देने योग्य है कि एक आउटपुट में दोषरहित एन्कोडिंग परिणाम के लिए libx264 की सेटिंग जो कि H.264 अनुरूप नहीं है और कुछ खिलाड़ियों पर टूटती है। लेकिन यह ओपी के आवेदन के लिए कम से कम उपयोगी हो सकता है।
जूल्स

दिलचस्प है कि क्या आपके पास कोई लिंक है? बग रिपोर्ट? यह भी ध्यान दें कि HuffyYUV के साथ एन्कोड किया गया वीडियो संभवतः "यूनी प्लेयर फ्रेंडली" नहीं है, मैं कल्पना
करूंगा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.