1

iOS 从 7.0.6 升级到 7.1.0 后,我们遇到了麻烦。我在运行 iOS 7.1 的 iPhone 4s、5、5c 和 5s 上都没有看到这个问题。我正在发布相机初始化代码:

- (void)initCapture
{
    //Setting up the AVCaptureDevice (camera)
    AVCaptureDevice* inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    NSError* cameraError;
    if ([inputDevice lockForConfiguration:&cameraError])
    {
        if ([inputDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus])
        {
            NSLog(@"AVCaptureDevice is set to video with continuous auto focus");
            CGPoint autofocusPoint = CGPointMake(0.5f, 0.5f);
            [inputDevice setFocusPointOfInterest:autofocusPoint];
            [inputDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
        }

        [inputDevice unlockForConfiguration];
    }

    //setting up the input streams
    AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:nil];

    //setting up up the AVCaptureVideoDataOutput
    AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init];
    captureOutput.alwaysDiscardsLateVideoFrames = YES;
    [captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

    //setting up video settings
    NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
    NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
    NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];

    //passing the settings to the AVCaptureVideoDataOutput
[captureOutput setVideoSettings:videoSettings];

    //setting up the AVCaptureSession
    captureSession = [[AVCaptureSession alloc] init];
    captureSession.sessionPreset = AVCaptureSessionPresetMedium;

    [captureSession addInput:captureInput];
    [captureSession addOutput:captureOutput];

    if (!prevLayer)
{
        prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
    }
    NSLog(@"initCapture preview Layer %p %@", self.prevLayer, self.prevLayer);
    self.prevLayer.frame = self.view.bounds;
    self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    [self.view.layer addSublayer: self.prevLayer];

    [self.captureSession startRunning];
}

任何帮助将不胜感激...

4

4 回答 4

1

您使用的 Apple 提供的代码已经过时 - 他们现在已经完全重写了。我会碰碰运气并采用新的工作流程。

在这里查看。

于 2014-04-08T17:14:17.717 回答
1

为了结束这个线程,除了 libzxing 之外,我们还使用相机扫描 QR 码。我们决定实现原生 iOS 7.0 AVCaptureMetadataOutputObjectsDelegate,而不是旧的 AVCaptureVideoDataOutputSampleBufferDelegate。元数据委托更简单、更干净,我们发现http://nshipster.com/ios7/中的示例非常有用。

于 2014-04-10T20:39:05.780 回答
0

以下是一些诊断您的问题的想法:

  • 你没有别的理由了if ([inputDevice lockForConfiguration:&cameraError])。添加一个。
  • 在 else 情况下,记录包含在cameraError.
  • 你没有别的理由了if ([inputDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus])。添加一个;记录它,或者在那里添加一个断点来测试你的调试。
  • focusPointOfInterestSupported在尝试之前,您不会检查属性的返回值setFocusPointOfInterestsetFocusMode考虑之前打电话setFocusPointOfInterest(不确定是否重要,但这就是我所拥有的)
  • 通常,您可能希望在尝试锁定配置之前进行所有检查。
于 2014-04-08T19:11:49.337 回答
0

在 neuman8 的评论指出 libzxing 中的某些内容阻止了重新聚焦之后,我自己做了一些调查,

我发现 Decoder.mm 文件中的以下行是罪魁祸首。

ArrayRef<char> subsetData (subsetBytesPerRow * subsetHeight);

看来 ArrayRef 是 zxing/common/Array.h 文件中的一个类,它试图分配一个指定大小的数组。它似乎没有做错任何事情,但我猜想分配大约 170k char 元素数组可能需要一些时间,并且是减慢阻塞调用以阻止其他线程运行的罪魁祸首。

因此,我尝试使用蛮力解决方案来检验假设。我在分配后添加了一个睡眠。

[NSThread sleepForTimeInterval:0.02];

相机再次开始对焦,并能够破译二维码。

我仍然无法找到更好的方法来解决这个问题。有没有人能够更有效地分配大型阵列,或者有更优雅的方式为相机焦点产生线程?
否则这应该可以解决现在的问题,即使它很丑陋。

于 2014-08-23T04:47:29.767 回答