2017-01-07 14 views
5

मैं कैमरा 2 (गैलेक्सी एस 7) के लिए पूर्ण क्षमता वाले एंड्रॉइड डिवाइस पर फिक्स्ड फ़्रेमेट्स (अधिमानतः 30 तक) के साथ छवि अनुक्रमों को सहेजने की कोशिश कर रहा हूं, लेकिन मैं एक स्थिर फ्रेमरेट प्राप्त करने में असमर्थ हूं, बी) 20fps तक पहुंचें (जेपीईजी एन्कोडिंग के साथ)। मैंने पहले ही Android camera2 capture burst is too slow से सुझाव शामिल किए हैं।एंड्रॉइड कैमरा 2 जेपीईजी फ्रैमरेट

जेपीईजी के लिए न्यूनतम फ्रेम अवधि 33.33 मिलीसेकंड (1920x1080 नीचे प्रस्तावों के लिए)

characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputMinFrameDuration(ImageFormat.JPEG, size); 

के अनुसार है और stallduration हर आकार (YUV_420_888 के लिए समान) के लिए 0ms है।

मेरे कब्जा बिल्डर के रूप में निम्नानुसार है:

captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF); 
captureBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, _exp_time); 
captureBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true); 

captureBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, _iso_value); 

captureBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, _foc_dist); 
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CONTROL_AF_MODE_OFF); 

captureBuilder.set(CaptureRequest.CONTROL_AWB_MODE, _wb_value); 

// https://stackoverflow.com/questions/29265126/android-camera2-capture-burst-is-too-slow 
captureBuilder.set(CaptureRequest.EDGE_MODE,CaptureRequest.EDGE_MODE_OFF); 
captureBuilder.set(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE, CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF); 
captureBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_OFF); 
captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL); 

// Orientation 
int rotation = getWindowManager().getDefaultDisplay().getRotation();   
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation)); 

फोकस दूरी 0.0 (inf) पर सेट है, आईएसओ 100 पर सेट है, जोखिम-समय 5ms। श्वेत संतुलन को बंद/ऑटो/किसी भी VALUE पर सेट किया जा सकता है, यह नीचे के समय को प्रभावित नहीं करता है।

session.setRepeatingRequest(_capReq.build(), captureListener, mBackgroundHandler); 

नोट::

मैं निम्न आदेश के साथ कब्जा सत्र शुरू करता है, तो मैं RepeatingRequest या RepeatingBurst का अनुरोध यह एक फर्क नहीं पड़ता ..

पूर्वावलोकन में (केवल बनावट सतह संलग्न) , सब कुछ 30fps पर है। हालांकि, जैसे ही मैं एक छवि रीडर (श्रोता HandlerThread पर चल रहा है), जो मैं इस प्रकार की तरह का दृष्टांत (बचत, फ्रेम के बीच समय केवल मापने के बिना) देते हैं के रूप में:

reader = ImageReader.newInstance(_img_width, _img_height, ImageFormat.JPEG, 2); 
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler); 
समय को मापने के कोड के साथ

:

ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() { 
    @Override 
    public void onImageAvailable(ImageReader myreader) { 
     Image image = null; 

     image = myreader.acquireNextImage(); 
     if (image == null) { 
      return; 
     } 
     long curr = image.getTimestamp(); 
     Log.d("curr- _last_ts", "" + ((curr - last_ts)/1000000) + " ms"); 
     last_ts = curr; 
     image.close(); 
    } 
} 

मैं समय-समय पर दोहरा हो इस तरह समय मतभेद:

99 एमएस - 66 एमएस - 66 एमएस - 99 एमएस - 66 एमएस - 66 एमएस ...

मुझे समझ में नहीं आ रहा है कि ये जेपीईजी के लिए स्ट्रीम कॉन्फ़िगरेशन मानचित्र का विज्ञापन करने के लिए डबल या ट्रिपल क्यों लेते हैं? एक्सपोजर समय 33 एमएमएस की फ्रेम अवधि से काफी नीचे है। क्या कोई अन्य आंतरिक प्रसंस्करण हो रहा है जिसके बारे में मुझे पता नहीं है?

मैंने YUV_420_888 प्रारूप के लिए इसे आजमाया, जिसके परिणामस्वरूप 33ms का निरंतर समय-अंतर हुआ। मेरी समस्या यह है कि सेलफोन में बैंडविड्थ की कमी है ताकि छवियों को तेज़ी से स्टोर किया जा सके (मैंने How to save a YUV_420_888 image? में वर्णित विधि की कोशिश की)। यदि आप इन छवियों को संपीड़ित या एन्कोड करने के किसी भी तरीके के बारे में जानते हैं, तो कृपया मुझे पर्याप्त बताएं, कृपया मुझे बताएं।

संपादित करें: getOutputStallDuration के प्रलेखन से:। "दूसरे शब्दों में, एक दोहरा YUV अनुरोध का उपयोग कर एक स्थिर फ्रेम दर में परिणाम होगा (मान लें कि यह 30 एफपीएस किए जाने पर) एक एकल जेपीईजी अनुरोध समय-समय पर प्रस्तुत किया जाता है, फ्रेम दर होगा 30 एफपीएस पर रहें (जब तक हम पिछले जेपीईजी को हर बार लौटने की प्रतीक्षा करते हैं)। अगर हम दोहराए गए वाईयूवी + जेपीईजी अनुरोध जमा करने का प्रयास करते हैं, तो फ्रेम दर 30 एफपीएस से गिर जाएगी। " क्या इसका मतलब है कि मुझे समय-समय पर एक कैप्चर() का अनुरोध करने की आवश्यकता है?

EDIT2: https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html से:। "आवेदन के लिए आवश्यक जानकारी, ऊपर मॉडल को देखते हुए android.scaler.streamConfigurationMap क्षेत्र के माध्यम से getOutputMinFrameDuration (पूर्णांक, आकार) का उपयोग करते हुए प्रदान की जाती है ये अधिकतम फ्रेम दर निर्धारित करने के लिए उपयोग किया जाता है/न्यूनतम फ्रेम अवधि जो किसी दिए गए स्ट्रीम कॉन्फ़िगरेशन के लिए संभव है।

विशेष रूप से, आवेदन निम्नलिखित नियमों का उपयोग कर सकते न्यूनतम फ्रेम अवधि में यह कैमरा डिवाइस से अनुरोध कर सकते हैं निर्धारित करने के लिए:

वर्तमान में कॉन्फ़िगर इनपुट के सेट करते हैं/आउटपुट धाराओं न्यूनतम फ्रेम का पता लगाएं एस के नाम से जाना getOutputMinFrameDuration (int, आकार) (इसके संबंधित आकार/प्रारूप के साथ) का उपयोग करके एंड्रॉइड.scaler.streamConfigurationMap में इसे देखकर, एस में प्रत्येक स्ट्रीम के लिए अवधि। फ्रेम अवधि के इस सेट को एफ कहा जाता है किसी भी अनुरोध के लिए आर, आर के लिए अनुमत न्यूनतम फ्रेम अवधि एफ में सभी मानों में से अधिकतम है। आर में उपयोग की जाने वाली धाराओं को S_r कहा जाता है। यदि S_r में किसी भी स्ट्रीम में स्टाल टाइम नहीं है (GetOutputStallDuration (int, Size) में अपने संबंधित आकार/प्रारूप का उपयोग करके सूचीबद्ध है), तो F में फ्रेम अवधि स्थिर स्थिति फ्रेम दर निर्धारित करती है जो एप्लिकेशन को आर का उपयोग करने पर प्राप्त होगी

+0

यदि आप जेपीईजी के रूप में कैप्चरिंग कर रहे हैं, तो आपको प्रत्येक फ्रेम को संपीड़ित करने के लिए एन्कोडर की प्रतीक्षा करनी होगी। YUV_420_888 के रूप में कैप्चरिंग संपीड़न के बिना कच्ची कैमरा छवि लेता है। आप संभावित रूप से अन्य धागे पर जेपीईजी संपीड़न चलाने की कोशिश कर सकते हैं, लेकिन फिर आपको शायद यह पता चल जाएगा कि आप चलने के एक मिनट के भीतर CPU की थर्मल सीमा को भर देते हैं। क्या आप सुनिश्चित हैं कि हार्डवेयर जेपीईजी एन्कोडर भी चयनित संकल्प के साथ 30fps पर चलने में सक्षम है? ऐसा लगता है जैसे यह नहीं है। आपके विकल्प प्रतीत होते हैं: रिज़ॉल्यूशन या फ़्रेमेट को कम करें। – BitBank

+0

कृपया संपादन 2 देखें, यह एक टिप्पणी के लिए बहुत लंबा था। इस कथन से और उपरोक्त मानों से मेरी समझ यह है कि 30fps जेपीईजी संभव होना चाहिए। – TobiasWeis

+0

ऐसा लगता है जैसे आप दस्तावेज़ों को सही ढंग से पढ़ते हैं, लेकिन यह वास्तव में स्पष्ट नहीं है कि आप पूर्ण फ़्रेमेट जेपीईजी कैप्चर कर सकते हैं। मुझे लगता है कि इसके साथ आपका अनुभव दिखाता है कि यह वांछित framerate वितरित नहीं करेगा। – BitBank

उत्तर

1

एक दोहराई जाने वाली अनुरोध के रूप में। "जेपीईजी उत्पादन माध्यम से तख्ते लाने के लिए नहीं सबसे तेज़ तरीका है। आप सीधे एक ओपन का उपयोग कर Quad पर फ्रेम बनाकर बहुत तेजी से ऐसा कर सकते हैं।

फट कब्जा के लिए, एक तेज़ समाधान छवियों को एन्कोड किए बिना रैम पर कैप्चर करेगा, फिर एन्कोडिंग और उन्हें अतुल्यकालिक रूप से सहेज देगा।

On this website आप एफ कर सकते हैं इंडस्ट्री मल्टीमीडिया से संबंधित बहुत सारे उत्कृष्ट कोड।

This specific program एमपीईजी वीडियो से पिक्सेल डेटा लाने के लिए ओपनजीएल का उपयोग करता है। वीडियो के बजाए कैमरे को इनपुट के रूप में उपयोग करना मुश्किल नहीं है। आप मूल रूप से उल्लिखित कार्यक्रम से CodecOutputSurface कक्षा में उपयोग किए गए बनावट का उपयोग अपने कैप्चर अनुरोध के लिए आउटपुट बनावट के रूप में कर सकते हैं।

+0

"आप इसे बहुत तेज़ी से पूरा कर सकते हैं ..." से आपका क्या मतलब है? यह छवियों को प्राप्त करने या सहेजने के लिए आवश्यक समय को नहीं बदलेगा, है ना? यह उन्हें तेजी से दिखाने का एक तरीका है, या क्या मुझे कुछ याद आ रही है?रैम और मैन्युअल एन्कोडिंग के साथ विचार विस्फोटों के लिए ठीक हो सकता है, लेकिन मैं लंबे समय तक (कम से कम 10 मिनट) स्थिर फ़्रेमेट्स पर अनुक्रमों को कैप्चर करने का एक तरीका ढूंढ रहा हूं। – TobiasWeis

+0

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

1

मुझे मिला एक संभावित समाधान में यूयूवी का उपयोग करके एक माइक्रो एसडी-कार्ड के साथ संयोजन में जेपीईजी के रूप में एन्कोड किए बिना होता है जो प्रति सेकंड 95 एमबी तक सहेजने में सक्षम होता है। (मुझे गलत धारणा थी कि वाईयूवी छवियां बड़ी होंगी, इसलिए एक सेलफोन के साथ जिसमें कैमरा 2-पाइपलाइन के लिए पूर्ण समर्थन है, लिखने की गति सीमित कारक होनी चाहिए।

इस सेटअप के साथ, मैं निम्नलिखित प्राप्त करने में सक्षम था स्थिर दर:

  • 1920x1080, 15fps (। लगभग 4Mb * 15 == 60MB/सेकंड)
  • 960x720, 30fps (लगभग 1.5 * 30 == 45Mb/सेक।)

। मैं फिर एक पायथन लिपि का उपयोग कर यूयूवी से पीएनजी तक ऑफ़लाइन छवियों को एन्कोड करता हूं।

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