سؤال

هدفي هو كتابة مخصص لعرض الكاميرا تحكم:

  1. يمكن التقاط الصور في كل أربعة واجهة التوجهات مع كل من الخلف و عندما تتوفر الكاميرا الأمامية.
  2. صحيح تدور جداول المعاينة "فيديو" فضلا عن دقة الصور.
  3. يسمح (بسيطة) على أن يطبق على كل من المعاينة "فيديو" كامل القرار الصور.

تنفيذ (على دائرة الرقابة الداخلية 4.2 / كسكودي 3.2.5):

بسبب شرط (3), أنا في حاجة إلى إسقاط AVFoundation.

لقد بدأت مع التقنية Q&A QA1702 ومن هذه التغييرات:

  1. غيرت sessionPreset إلى AVCaptureSessionPresetPhoto.
  2. وأضاف AVCaptureStillImageOutput إضافي الإخراج قبل بدء الدورة.

المشكلة التي أعاني مع أداء معالجة صورة المعاينة (إطار المعاينة "فيديو").

أولا: يجب على UIImage نتيجة imageFromSampleBuffer: على عينة العازلة من captureOutput:didOutputSampleBuffer:fromConnection:.ثم أنا نطاق وتناوب عليها على الشاشة باستخدام CGGraphicsContext.

عند هذه النقطة, معدل الإطار هو بالفعل تحت 15 إطارا في الثانية المحدد في إخراج الفيديو من الدورة عندما تضيف في الواقع ، فإنه يسقط تحت أو حول 10.بسرعة تعطل التطبيق بسبب انخفاض الذاكرة.

لقد حققت بعض النجاح مع اسقاط معدل الإطار إلى 9 FPS على اي فون 4 و 8 FPS على جهاز iPod Touch (4th gen).

لقد أضاف أيضا في بعض رمز "دافق" ارسال قائمة الانتظار, ولكن أنا لست متأكدا كم هو في الواقع مساعدة.أساسا كل 8-10 إطارات العلم هو مجموعة إشارات captureOutput:didOutputSampleBuffer:fromConnection: للعودة على الفور بدلا من عملية الإطار.العلم هو إعادة تعيين بعد عملية متزامنة على إخراج ارسال قائمة الانتظار التشطيبات.

عند هذه النقطة أنا لا أمانع من انخفاض معدلات الإطار ، ولكن من الواضح أننا لا يمكن أن تأتي مع ذاكرة منخفضة تعطل.أي شخص لديه أي فكرة عن كيفية اتخاذ إجراءات لمنع ظروف الذاكرة المنخفضة في هذه الحالة (و/أو طريقة أفضل "دافق" ارسال قائمة الانتظار)?

هل كانت مفيدة؟

المحلول

لمنع مشاكل الذاكرة ، ببساطة إنشاء تجمع autorelease في captureOutput:didOutputSampleBuffer:fromConnection:.

وهذا أمر منطقي لأن imageFromSampleBuffer: بإرجاع autoreleased UIImage الكائن.بالإضافة إلى أنه يحرر أي autoreleased الكائنات التي تم إنشاؤها عن طريق معالجة الصور رمز الحق بعيدا.

// Delegate routine that is called when a sample buffer was written
- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
fromConnection:(AVCaptureConnection *)connection
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // Create a UIImage from the sample buffer data
    UIImage *image = [self imageFromSampleBuffer:sampleBuffer];

    < Add your code here that uses the image >

    [pool release];
}

بلدي التجارب أثبتت أن هذا سوف تعمل دون ذاكرة تحذيرات على اي فون 4 أو آي بود تاتش (4th gen) حتى إذا طلب FPS عالية جدا (مثلا ، 60) ومعالجة الصور بطيئة جدا (مثلا ، 0.5+ ثانية).

حل:

كما براد أشار أبل توصي معالجة الصور تكون على خلفية الموضوع حتى لا تتداخل مع استجابة واجهة المستخدم.لم ألاحظ تأخر كثيرا في هذه الحالة ، ولكن أفضل الممارسات أفضل الممارسات ، وذلك باستخدام محلول أعلاه مع تجمع autorelease بدلا من تشغيل هذه الرئيسي ارسال قائمة الانتظار / الترابط الرئيسي.

لمنع مشاكل الذاكرة, ببساطة استخدام الرئيسي ارسال قائمة الانتظار بدلا من إنشاء واحدة جديدة.

وهذا يعني أيضا أن لم يكن لديك للتبديل إلى الخيط الرئيسي في captureOutput:didOutputSampleBuffer:fromConnection: عندما تريد تحديث واجهة المستخدم.

في setupCaptureSession, تغيير من:

// Configure your output.
dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);

إلى:

// we want our dispatch to be on the main thread
[output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

نصائح أخرى

الأساس الأفضل استخدام OpenGL للتعامل مع الكثير من الصور ذات الأحمال الثقيلة بالنسبة لك (كما أرى أنك تحاول في آخر محاولة).ومع ذلك ، حتى ثم قد يكون لديك مشاكل مع بناء إطارات معالجتها.

في حين يبدو غريبا التي سوف تكون قيد التشغيل في الذاكرة تراكم عند معالجة الإطارات (في تجربتي, تستطيع التوقف عن الحصول عليها إذا كنت لا يمكن معالجتها بسرعة كافية), Grand Central Dispatch طوابير يمكن الحصول على التشويش حتى إذا كانوا ينتظرون على I/O.

وربما إرسال إشارة تتيح لك خنق إضافة عناصر جديدة إلى تجهيز قوائم الانتظار.لمزيد من المعلومات حول هذا ، وأنا أوصي مايك الرماد "GCD العملي"المادة, حيث يبدو في تحسين I/O bound مصغرة تجهيز العملية باستخدام إرسال الإشارات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top