2010-09-24 8 views
7

मैं वर्तमान में .NET से libavutil, libavformat और libavcodec (FFMpeg का सभी भाग) तक पहुंचने के लिए देख रहा हूं।क्या .NET में FFMpeg, libavutil, libavformat और libavcodec के लिए काम करने वाले पी/Invoke घोषणाओं का एक सेट है?

वर्तमान में, मैं libraries from the automated builds of the shared FFMpeg package प्रदर्शन विंडोज 32-बिट के लिए हर रात हो रही है।

मैं भी ffmpeg-sharp project से कोड का उपयोग कर रहा हूँ। उस प्रोजेक्ट में, मैंने कई वर्गों को हटा दिया है जो संकलित नहीं कर रहे थे (वे रैपर वर्ग हैं जो पी/आमंत्रण घोषणा नहीं करते हैं)।

कोड ठीक संकलित करता है, लेकिन मैं कुछ मुद्दों में भाग रहा हूं।

सबसे पहले, यह है कि ए वी * .dll के निर्माण cdecl calling convention का उपयोग करता है, जैसा कि मैंने PInvokeStackImbalanceException के एक नंबर प्राप्त था जब av_open_input_file कॉल करने के लिए कोशिश कर रहा प्रतीत होता है। यह सही काम करने के लिए इसे बदलने के लिए काफी आसान था। AVFormatContext संरचना आबादी है।

उसके बाद, मैं av_find_stream_info कॉल करने के लिए फ़ाइल में धाराओं के बारे में जानकारी प्राप्त करना चाहते हैं। हालांकि, जब AVFormatContext को कॉल से av_open_input_file पर पुनर्प्राप्त किया गया, तो AccessViolationException इंगित किया गया है कि मैं संरक्षित स्मृति से पढ़ने या लिखने की कोशिश कर रहा हूं।

किसी को भी पी/आह्वान के माध्यम से libavutil, libavformat और libavcodec dll पुस्तकालयों का उपयोग करने के पी/आह्वान इस्तेमाल किया गया है और यह काम करने के लिए मिल गया है?

मैं उल्लेख करना चाहिए कि, ffmpeg के कमांड लाइन संस्करण के साथ काम करते हुए एक समाधान, इस मामले में एक व्यवहार्य समाधान नहीं है, का उपयोग पुस्तकालयों के माध्यम से हो की जरूरत है। इसका कारण यह है कि मुझे ऐसा करने के लिए डिस्क मार्ग को बहुत अधिक करना होगा जो मुझे करना है (मुझे कुछ बहुत ही उच्च परिभाषा वीडियो के फ्रेम-दर-फ्रेम विश्लेषण करना है) और मैं डिस्क से बचना चाहता हूं जितना संभव।

+0

पुन: डिस्क ताड़ना चिंताओं, मैं सिर्फ ffmpeg उत्पादन पर कब्जा करने के साथ कुछ सफलता प्राप्त की - हाँ सामग्री, नहीं मेटाडाटा - stdout पाइप के माध्यम से। यदि यह आपके परिदृश्य में फिट हो सकता है, तो कोई फ़ाइल नहीं है और यह डिस्क को हिट नहीं करती है। –

उत्तर

2

यह वही है जो मैंने पाया - अर्थात्, ffmpeg-sharp project में पी/Invoke घोषणाओं की एक अच्छी राशि गलत है। वहां बहुत अच्छी जगहें हैं जहां वे घोषणाओं में संरचनाओं का उपयोग करते हैं, जिन्हें बाद में मार्शल किया जाता है, लेकिन बाद में, उन्हें बाद में डीलोकेशन दिनचर्या में पारित किया जाना चाहिए।

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

समाधान IntPtr लेने/वापस करने के लिए अपनी एपीआई घोषणाओं को बदलने और आवश्यकतानुसार संरचनाओं के मार्शलिंग को निष्पादित करना है, उन्हें पी/आमंत्रण घोषणाओं में शामिल न करने के लिए।

+0

अब मैं एक साधारण .NET wrapper की तलाश कर रहा हूं जिसे एक वैश्विक कनवर्ट विधि का खुलासा करना चाहिए और ffmpeg का उपयोग करना चाहिए। प्रत्येक बार इसकी प्रगति में बदलाव होने पर मुझे एक घटना को बढ़ाने के लिए भी इसकी आवश्यकता होती है, इसलिए मैं इसे अतुल्यकालिक रूप से चला सकता हूं और प्रतिशत को उपयोगकर्ता के साथ सूचित कर सकता हूं। – Shimmy

+0

अब मुझे वास्तव में आपसे पूछना है: क्या उन्होंने सही किया? –

0

मैंने उन पुस्तकालयों/परियोजनाओं में से किसी से स्पष्ट किया है। उस समय मैंने जो सारी जानकारी पाई, उन लोगों को इंगित किया जो नए संस्करणों के साथ बहुत आसानी से तोड़ रहे हैं और/या बस बहुत पुराना हो रहा है।

मैंने जो किया है वह एफएमपीपीईजी प्रक्रिया को सीधे चलाया गया है, जैसा कि मैंने this answer पर उल्लेख किया है, एक ब्लॉग पोस्ट में नमूना संशोधित करके मैं वहां लिंक करता हूं। इस तिथि करने के लिए हम मुसीबत नहीं मिला है इसके साथ :)

यदि उपरोक्त अपने परिदृश्य, अच्छे भाग्य के लिए काम नहीं करता।

+0

मैंने प्रश्न संशोधित किया, लेकिन मुझे यह उल्लेख करना चाहिए कि कमांड लाइन का उपयोग करना एक विकल्प नहीं है। मुझे ऐसा करने के लिए डिस्क मार्ग को बहुत अधिक करना होगा जो मुझे करना है (मुझे कुछ बहुत ही उच्च परिभाषा वीडियो के फ्रेम-दर-फ्रेम विश्लेषण करना है) और मैं जितना संभव हो डिस्क से बचना चाहता हूं। – casperOne

+0

मैं इसे नहीं किया है, लेकिन आप उत्पादन रीडायरेक्ट करने के लिए डिस्क पर जाने के लिए यह – eglasius

+0

हड़पने के लिए मैं इसे बाहर figurd होने से बचने के लिए सक्षम हो सकता है, नीचे मेरा उत्तर देखें। यह और अधिक है कि कैसे ffmpeg-sharp हैंडल पी/Invoke। मैं अब स्मृति में फ़ाइलों से स्ट्रीम/कोडेक जानकारी प्राप्त करने में सक्षम हूं। – casperOne

0

SharpFFmpeg आयात C++ पुस्तकालय। सी ++ कोड एक अप्रबंधित कोड है। इसे अप्रबंधित स्मृति के लिए पॉइंटर्स की आवश्यकता है।"मार्शल" कक्षा अप्रबंधित स्मृति आवंटित करने के लिए कुछ विधि प्रदान करती है। उदाहरण के लिए:

IntPtr buffer = Marshal.AllocHGlobal(buf.Length + FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE); //buf is a byte array 

इसके अलावा, अगर आप कार्य करने के लिए एक प्रबंधित चर (किसी भी सी # चर) भेजना चाहते हैं, तो आप अप्रबंधित स्मृति को मार्शल करने के लिए (कॉपी) इस चर है।

for (int i = 0; i < buf.Length; i++) 
     Marshal.StructureToPtr(buf[i], buffer + i, true); 

अब आप फ़ंक्शन में पॉइंटर भेज सकते हैं।

FFmpeg.avcodec_decode_video(codecContextUnmanaged, frame, ref success, buffer, buf.Length); 

यह संभव है कि आपको कुछ अप्रबंधित संरचनाओं को संशोधित करने की आवश्यकता होगी। ऐसा करने के लिए आपको संरचना को एक प्रबंधित मेमोरी (मार्शल.पीटीटीओस्ट्रक्चर विधि) में कॉपी करना होगा, फिर इसे संशोधित करें, और इसे एक अप्रबंधित स्मृति में दोबारा कॉपी करें।
मैं एक ही समस्या एक बहुत द्वारा सताया गया था। मैंने इसे हल किया, लेकिन मैं वैसे भी वीडियो डीकोड नहीं कर सकता)) मुझे आशा है कि मेरा समाधान किसी की भी मदद करेगा।

संबंधित मुद्दे