Trying to implement a counter. The bottom line is that some line should be transmitted to the smartphone screen at a frame rate, that is, 20-30 times per second.

I realize this beauty with the help of frame transfer. Something like this:

CODE UPDATE (5:00 pm; 07/01/2016 EST)

//.h file #import <UIKit/UIKit.h> int N = 0; //Глобальная переменная для подсчета кадров @interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *Label; //строка на экране @end //.m file #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewController () @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end @implementation ViewController { AVCaptureSession *session; } - (void)viewDidLoad { [super viewDidLoad]; [self setupCaptureSession]; } - (void)setupCaptureSession //инициализация сессии съемки { NSError *error = nil; session = [[AVCaptureSession alloc] init]; session.sessionPreset = AVCaptureSessionPresetMedium; AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; if (!input) { } [session addInput:input]; AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init]; dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL); //создание очереди кадров [output setSampleBufferDelegate:self queue:queue];// создание буфера сэмплов и добавление очереди [session addOutput:output]; [session startRunning]; } //В методе строкой ниже, осуществляется передача кадров с камеры в буфер - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { NSString *text = [NSString stringWithFormat: @"N = %d", N]; //to create string with global variable N self.Label.text = text; //вывести строку на экран айфона NSLog(text); //распечатать строку в консоль N++; } @end 

The transfer is obtained, but sooo slow. The line on the screen is updated no earlier than 10 seconds after the launch of the application. And moreover, sometimes I launch the application, and the line does not want to be updated at all.

Question: Is there a way to more effectively transfer the string to the screen of the smartphone? How to do it right?

  • check that this whole thing happens on main thread - Max Mikheyenko
  • @Max Mikheyenko and how to check? I'm almost noob. - Andrew Kachalin
  • AVCaptureVideoDataOutput has a property sampleBufferCallbackQueue where you can specify the stream on which to call your method. pass the main thread there. - Max Mikheyenko

1 answer 1

20-30 times per second to update the line for the device is not a problem at all. But it is worth checking how often the captureOutput: didOutputSampleBuffer: method is called. If he is rarely called, then nothing can be done. Add in this method output to the log.

Try to update the UI like this (so that it was exactly from the main thread):

 dispatch_async(dispatch_get_main_queue(), ^{ // Update UI self.Label.text = text; }); 
  • The method is well invoked. Just 20 times a second. NSLog(@"sometext "); - pops up also in proportion to the method. But the update on the smartphone screen is slower. (Sometimes I launch it - it is not updated at all). - Andrew Kachalin
  • dispatch_async not helped? Then you can try dispatch_sync or update other components (cells, buttons) or other properties (frame, alpha, image). Especially carefully try with UIImageView - Valentine
  • a little bit unclear. I added the code to the question. Can you say more specifically, where should I add the dispatch_asynk ? - Andrew Kachalin
  • dispatch_async needs to be added to the captureOutput method: didOutputSampleBuffer: Roughly speaking, the interface update should be in the dispatch_async block - Valentine
  • thank. It all worked. - Andrew Kachalin