नमस्ते! यह आलेख
विज़ुअल स्टूडियो के साथ मेरे FFmpeg लेख की निरंतरता है
। यहाँ हम FULL HD RTSP स्ट्रीम के हार्डवेयर डिकोडिंग के लिए उतरते हैं। मैं पहले से कहूंगा कि इंटेल एटम Z8350 भी आसानी से इस कार्य का सामना कर सकता है।
उद्देश्य: एक RTSP h.264 आईपी कैमरा से बाद के समानांतर प्रसंस्करण (चार प्रोसेसर कोर) के लिए रैम में 4 फ्रेम तक हार्डवेयर डिकोडिंग और रिकॉर्डिंग। मैं WinAPI फ़ंक्शन का उपयोग करके संसाधित फ़्रेम प्रदर्शित करता हूं। नतीजतन, हम समानांतर मोड में आरटीएसपी स्ट्रीम के कंप्यूटर प्रसंस्करण के लिए एक उच्च गति प्रणाली प्राप्त करते हैं। इसके बाद, आप
रीयल टाइम फ़्रेम को संसाधित करने के लिए
कंप्यूटर विज़न एल्गोरिदम को कनेक्ट कर सकते हैं।
प्रविष्टि
मुझे हार्डवेयर डिकोडिंग की आवश्यकता क्यों है? आप कमजोर और सस्ते प्रोसेसर के साथ वास्तविक समय के वीडियो को डिकोड करना चाहते हैं या आप जितना संभव हो उतना प्रोसेसर को अनलोड करना चाहते हैं, तो हार्डवेयर डिकोडिंग से परिचित होने का समय है।
DirectX वीडियो एक्सेलेरेशन (DXVA) GPU के साथ वीडियो प्रसंस्करण में तेजी लाने के लिए हार्डवेयर त्वरण का उपयोग करने के लिए एक एपीआई है। DXVA 2.0 आपको वीडियो कैप्चर और वीडियो प्रसंस्करण कार्यों सहित GPU के लिए और अधिक संचालन को पुनर्निर्देशित करने की अनुमति देता है।
पिछला लेख लिखने के बाद, मुझसे काफी सवाल पूछे गए: "इसका इस्तेमाल FFmpeg क्यों किया जाता है?" मैं समस्याओं के साथ शुरू करता हूँ। हार्डवेयर डिकोडिंग की मुख्य कठिनाई रैम को डिकोड किए गए फ्रेम को लिखना है। पूर्ण HD के लिए, यह 1920 x 1080 x 3 = 6,220,800 बाइट्स है। यहां तक कि इस तथ्य को ध्यान में रखते हुए कि फ्रेम NV12 प्रारूप में संग्रहीत है, यह भी 1920 x 1080 x 1.5 = 3 110 400 बाइट्स का एक बहुत है। किसी भी प्रोसेसर के लिए 75 एमबी प्रति सेकंड ओवरराइटिंग एक गंभीर काम है। इस समस्या को हल करने के लिए, इंटेल ने SSE 4 कमांड्स को जोड़ा है, जो आपको प्रोसेसर के बिना डेटा को फिर से लिखने की अनुमति देता है। दुर्भाग्य से, सभी पुस्तकालयों ने इसे लागू नहीं किया है। मैंने निम्नलिखित पुस्तकालयों का परीक्षण किया है:
- FFmpeg
- वीएलसी
- OpenCV
वीएलसी - हार्डवेयर डिकोडिंग (बहुत कम प्रोसेसर लोड) के माध्यम से आईपी कैमरों के साथ काम करता है, एक आदिम आरटीएसपी स्ट्रीम प्लेयर कोड की सिर्फ 10 लाइनों में बनाया जा सकता है, लेकिन रैम में डिकोड किए गए फ्रेम प्राप्त करने में बहुत अधिक प्रोसेसर समय लगता है।
OpenCV - RTSP स्ट्रीम के साथ काम करने के लिए FFmpeg का उपयोग करता है, इसलिए यह बिचौलियों के बिना काम करने का निर्णय लिया गया था, अर्थात। FFmpeg लाइब्रेरी का उपयोग करें। इसके अलावा, FFmpeg, जो डिफ़ॉल्ट रूप से स्थापित है, हार्डवेयर डिकोडिंग के बिना OpenCV में बनाया गया है।
FFmpeg - मेरी राय, परिणाम में अच्छा है, यह काफी काम करता है। Windows में X86 (X64 आपको काम करने की अनुमति देता है) के लिए WEB- कैमरों के साथ काम करने में एकमात्र दोष लागू नहीं होता है।
हार्डवेयर वीडियो डिकोडिंग आसान है
वास्तव में, FFmpeg लाइब्रेरी का उपयोग करने वाला हार्डवेयर डिकोडिंग सॉफ़्टवेयर से अधिक जटिल नहीं है। परियोजना सेटिंग्स सॉफ्टवेयर कार्यान्वयन के लिए समान हैं, ब्लॉक आरेख अपरिवर्तित रहे।
आप FFmpeg समर्थित हार्डवेयर डिकोडिंग विधियों की एक सूची प्रदर्शित कर सकते हैं।
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
पहली चीज जो हमें करने की ज़रूरत है वह है एफएफएमपीई जिसके साथ हार्डवेयर डिकोडर आप वीडियो को डिकोड करना चाहते हैं। मेरे मामले में, Windows10 + इंटेल एटम Z8350 केवल DXVA2 छोड़ता है:
type = av_hwdevice_find_type_by_name("dxva2");
आप हार्डवेयर डिकोडर के रूप में CUDA, D3D11VA, QSV या VAAPI (केवल Linux) चुन सकते हैं। तदनुसार, आपके पास यह हार्डवेयर समाधान होना चाहिए और FFmpeg को इसके समर्थन के साथ बनाया जाना चाहिए।
वीडियो स्ट्रीम खोलें:
avformat_open_input(&input_ctx, filename, NULL, NULL;
हमें वीडियो स्ट्रीम के बारे में जानकारी मिलती है:
av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
स्मृति आवंटित करें:
frame = av_frame_alloc();
यह फ़ंक्शन रैम में डिकोड की गई फ़ाइल को ओवरराइट करता है:
av_hwframe_transfer_data(sw_frame, frame, 0);
NV12 प्रारूप के बारे में थोड़ा
इसलिए, हमें sw_frame संरचना में एक फ्रेम मिला है। प्राप्त फ्रेम NV12 प्रारूप में संग्रहीत है। यह प्रारूप Microsoft द्वारा आविष्कार किया गया था। यह आपको 12 बिट्स में पिक्सेल जानकारी स्टोर करने की अनुमति देता है। जहां 8 बिट्स की तीव्रता है, और 4 बिट्स रंग का वर्णन करते हैं (या बल्कि, रंग तुरंत 4 आसन्न 2x2 पिक्सल के लिए वर्णित है)। इसके अलावा, sw_frame.data [0] - तीव्रता संग्रहीत है, और sw_frame.data [1] में - रंग संग्रहीत है। NV-12 से RGB में बदलने के लिए, आप निम्न फ़ंक्शन का उपयोग कर सकते हैं:
सी ++ अनुवाद एनवी 12 से आरजीबी तक void SaveFrame(uint8_t * f1, uint8_t * f2, int iFrame) { FILE *pFile; char szFilename[32]; int x, i, j;
यद्यपि NV12 के साथ काम करने से आपको धुंधला हो जाना, रेटिनेक्स जैसी प्रक्रियाओं के कार्यान्वयन में तेजी लाने और ग्रेस्केल में छवियों को प्राप्त करने की अनुमति मिलती है (बस रंग को त्यागकर)। अपने कार्यों में, मैं NV12 प्रारूप को RGB में अनुवाद नहीं करता, क्योंकि इसमें अतिरिक्त समय लगता है।
और इसलिए हमने सीखा कि कैसे हार्डवेयर में वीडियो फ़ाइलों को डिकोड करें और उन्हें एक विंडो में प्रदर्शित करें। हम NV12 प्रारूप में मिले और इसे परिचित RGB में कैसे परिवर्तित करें।
Dll हार्डवेयर डिकोडिंग
FFmpeg 40 एमएस (25 फ्रेम प्रति सेकंड पर) के बाद फ्रेम जारी करता है। एक नियम के रूप में, एक पूर्ण HD फ्रेम प्रसंस्करण में काफी लंबा समय लगता है। इसके लिए सभी 4 प्रोसेसर कोर के लोड को अधिकतम करने के लिए मल्टीथ्रेडिंग की आवश्यकता होती है। अभ्यास में, मैं एक बार 6 धागे शुरू करता हूं और उन्हें अब नहीं हटाता हूं, जो काम को बहुत सरल करता है और कार्यक्रम की विश्वसनीयता बढ़ाता है। ऑपरेशन योजना को अंजीर में दिखाया गया है। 1
अंजीर। 1 FFmpeg के साथ एक बहु-थ्रेडेड प्रोग्राम बनाने की योजनामैंने अपनी परियोजनाओं में शामिल करने के लिए
* .dll * .dll (FFmpegD.DLL) के रूप में अपना डिकोडर लिखा। यह आपको प्रोजेक्ट के कोड को कम करने की अनुमति देता है, जो कोड की समझ को बढ़ाता है और इसे किसी भी प्रोग्रामिंग भाषा में शामिल करता है, असेंबलर (सत्यापित :)) तक। इसका उपयोग करते हुए, हम अपने आरटीएसपी स्ट्रीम प्लेयर को आईपी कैमरे से लिखेंगे।
DLL के साथ काम करना शुरू करने के लिए, आपको एक सूचक को एक इंट [13] सरणी, एक नए फ्रेम आगमन की घटना का एक HANDLE, कैमरा से एक नया डेटा पैकेट और कैमरा पता के एक चार सरणी को संसाधित करने के लिए पास करने की आवश्यकता है।
सरणी संरचना तालिका 1 में दी गई है।

कॉल करने से पहले, आपको फ्रेम नंबर 1-4 रीसेट करना होगा।
DLL FFmpeg को इनिशियलाइज़ करने के लिए सभी आवश्यक कदम उठाएगा और पॉइंटर्स और फ्रेम नंबर को रिकॉर्ड करेगा। इसके बाद यह घटना "नया फ्रेम आगमन" सेट करती है। केवल आने वाले फ़्रेमों को संसाधित करना और फ़्रेम नंबर के बजाय 0 लिखना आवश्यक है (इसका मतलब है कि फ़्रेम संसाधित हो गया है और अब उपयोग नहीं किया जाता है)।
नीचे आपको स्रोत कोड के साथ एक उदाहरण खिलाड़ी मिलेगा। इसका उदाहरण है ShowDib3 Charles Petzold।
→
प्रोजेक्ट के साथ पुरालेख→
FFmpegD.dll संग्रहपरिणाम: इंटेल एटम Z8350 पर FFmpeg हार्डवेयर मोशन डिटेक्टर भी वास्तविक समय में h264 पूर्ण HD से जुड़ा हुआ है और कनेक्ट मोशन डिटेक्टर के साथ 20% प्रोसेसर लोड के साथ है।
इंटेल एटम Z8350 पर मोशन डिटेक्टर ऑपरेशन उदाहरण। पहले 30 सेकंड पृष्ठभूमि की गणना है। उसके बाद, गति डिटेक्टर पृष्ठभूमि को घटाने की विधि द्वारा काम करता है।पुनश्च आप वीडियो फ़ाइलों (संपीड़ित h.264) को भी डीकोड कर सकते हैं !!!
संदर्भ:
- FFmpeg पर विविध उपयोगी जानकारी
- FFmpeg द्वारा प्रदान की गई विभिन्न पुस्तकालयों का उपयोग करने के बारे में जानकारी
- आरजीबी के लिए प्रारूप और रूपांतरण पर जानकारी