2010-11-23 12 views
5

मैं अपने एएसआईसी द्वारा कब्जे वाले फ्रेम को वापस चलाने के लिए एक वीडियो प्लेयर लिख रहा हूं। वे एक कस्टम प्रारूप में हैं, और मुझे एक ऐसे समारोह के साथ प्रदान किया गया है जो एएसआईसी राज्यों को डीकोड करता है। वीडियो 640x480 से 2560x1200 (!!!) तक कोई आकार हो सकता है। प्रत्येक राज्य चक्र का उत्पादन 16x16 ब्लॉक पिक्सेल है, जिसे मुझे स्क्रीन पर एक वीडियो में जाना है।डब्ल्यूपीएफ में वीडियो बनाने और खींचने का एक तेज़ तरीका क्या है?

हर बार स्क्रीन को अपडेट करना होगा, मुझे निम्नलिखित जानकारी है:

  • ब्लॉक चौड़ाई
  • ब्लॉक ऊंचाई
  • एक्स ब्लॉक के समन्वय शुरू
  • वाई ब्लॉक के समन्वय शुरू
  • आरजीबी 32 पिक्सेल रंग की जानकारी का 1-डी सरणी

मेजर सीमाएं:

  • .NET 3.5
  • कोई असुरक्षित कोड

मैं आज सुबह कुछ इस तरह एक WriteableBitmap बाहर की कोशिश कर रहा है, और एक छवि के लिए एक स्रोत के रूप में उपयोग, खर्च:

private WriteableBitmap ImageSource; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     ImageSource = new WriteableBitmap(FrameWidth, FrameHeight, 96, 96, PixelFormats.Bgr32, null); 
     ImagePanel.Source = ImageSource; 
    } 

    private void DrawBox(byte Red, byte Green, byte Blue, int X, int Y) 
    { 
     int BoxWidth = 16; 
     int BoxHeight = 16; 
     int BytesPerPixel = ImageSource.Format.BitsPerPixel/8; 

     byte[] Pixels = new byte[BoxWidth * BoxHeight * BytesPerPixel]; 

     for (int i = 0; i < Pixels.Length; i += 4) 
     { 
      Pixels[i + 0] = Blue; 
      Pixels[i + 1] = Green; 
      Pixels[i + 2] = Red; 
      Pixels[i + 3] = 0; 
     } 

     int Stride = BoxWidth * BytesPerPixel; 
     Int32Rect DrawBox = new Int32Rect(X, Y, BoxWidth, BoxHeight); 

     ImageSource.Lock(); 
     ImageSource.WritePixels(DrawBox, Pixels, Stride, 0); 
     ImageSource.Unlock(); 
    } 

यह काम करता है, मेरा वीडियो स्क्रीन पर चलता है, लेकिन यह sloooooooow है। वास्तविक समय की गति की गति के पास कहीं भी नहीं। प्रक्रियात्मक रूप से बिटमैप्स की एक श्रृंखला उत्पन्न करने के अलावा, ऐसा करने के लिए कोई बेहतर तरीका है, जिसे मैं नहीं देख रहा हूं? मैंने डी 3 डीमेज के बारे में कुछ पढ़ा है, लेकिन ऐसा लगता है कि एक बिटमैप में 3 डी दृश्य निर्यात करने के लिए और भी कुछ है। सुझाव यहाँ?

+0

DrawBox एक ठोस रंग का 16 * 16 पिक्सेल ब्लॉक बना रहा प्रतीत होता है। क्या ये सही है? –

+0

WriteableBitmap.WritePixels विधि (Int32Rect, Array, Int32, Int32, Int32) के साथ आपको लॉक और अनलॉक स्रोत का उपयोग करने की आवश्यकता नहीं है: http://msdn.microsoft.com/en-us/library/cc490065.aspx – Gorgen

+0

हां , ड्रॉबॉक्स कुछ ऐसा है जो मैं ठोस रंग के ब्लॉक को खींचने के लिए खेल रहा था। इसके अलावा, लॉकिंग पर धन्यवाद, अनुमान है कि मुझे करीब पढ़ना चाहिए था। – Stevoman

उत्तर

6

यदि मैं सही ढंग से समझता हूं तो आपको कैप्चर के रूप में 16 * 16 पिक्सेल ब्लॉक प्राप्त होता है, और ऊपर दिए गए उदाहरण में आप इन अद्यतनों में से प्रत्येक पर लिखने योग्य बिटमैप अपडेट कर रहे हैं।

यह बहुत सारे मंथन जैसा दिखता है क्योंकि प्रत्येक ब्लॉक पर रेंडर ट्रिगर किया जा रहा है।

  • एक एकल बाइट बफर होती हैं जो पूरे फ्रेम का प्रतिनिधित्व करता है बनाए रखें:

    बेहतर करने के लिए नहीं होगा।

  • अपने 16 * 16 ब्लॉक के साथ बफर को अपडेट करते समय अपडेट करें।
  • जब आपको फ्रेम के लिए सभी ब्लॉक प्राप्त हुए हैं, तो बफर को बिटमैप पर लिखें।
  • इसे आगे लिखकर अगले फ्रेम के लिए फ्रेम बफर का पुन: उपयोग करें।

इस तरह आप प्रतिपादन पर बहुत कम मंथन करेंगे क्योंकि आप प्राप्त प्रत्येक ब्लॉक के लिए एक रेंडर ट्रिगर नहीं करेंगे, बल्कि केवल प्रत्येक फ्रेम के लिए।

अद्यतन 1

मैं भी अपने पिक्सेल प्रारूप के रूप में Bgr24 का उपयोग कर यदि आप एक अल्फा चैनल का उपयोग नहीं कर रहे हैं पर विचार करेंगे। इस तरह आपके पास 4 की बजाय 3 बाइट प्रति पिक्सल होगा, इसलिए बहुत कम ओवरहेड।

अद्यतन 2

बातें अभी भी बड़े फ्रेम आकार के लिए बहुत धीमी गति से कर रहे हैं, तो आप भी जिसके बाद हालांकि जटिलता कहते हैं विचार कर सकते हैं।

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

अद्यतन 3

अपने कब्जा से अपने पिक्सेल रंग की जानकारी देता है सही प्रारूप में है, तो आप Buffer.BlockCopy थोक में प्रतिलिपि फ्रेम बफर सरणी में स्रोत पिक्सेल सारणी का उपयोग कर की कोशिश कर सकते। हालांकि आपको अपने बिटमैप प्रारूप को bgr32 के रूप में रखना होगा। यह निम्न स्तरीय सरणी प्रतिलिपि तकनीक कुछ प्रदर्शन लाभ प्राप्त कर सकती है।

+0

धन्यवाद! पृष्ठभूमि में बफर बनाने के लिए Buffer.BlockCopy का उपयोग करना, फिर प्रति फ्रेम एक बार WritePixels() को कॉल करना चाल था! – Stevoman

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

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