Ios 将视频写入文件在iPad3上正常工作约5秒钟,然后失败

Ios 将视频写入文件在iPad3上正常工作约5秒钟,然后失败,ios,ipad,avfoundation,avassetwriter,avassetwriterinput,Ios,Ipad,Avfoundation,Avassetwriter,Avassetwriterinput,我正在创建一个摄像头应用程序。因为它是为iOS 9创建的,所以我必须在旧设备上测试它。在这种情况下,ipad3。该应用程序在新的iPadPro 9.7上运行良好,但在iPad3上运行了一段时间后无法编写视频 发生的情况是,应用程序开始编写帧,但突然失败 我使用此方法存储每个帧: - (void)writeToFileFrame:(CIImage *) finalImage withSampleTime:(CMSampleTimingInfo)sampleTime

我正在创建一个摄像头应用程序。因为它是为iOS 9创建的,所以我必须在旧设备上测试它。在这种情况下,ipad3。该应用程序在新的iPadPro 9.7上运行良好,但在iPad3上运行了一段时间后无法编写视频

发生的情况是,应用程序开始编写帧,但突然失败

我使用此方法存储每个帧:

- (void)writeToFileFrame:(CIImage *) finalImage
          withSampleTime:(CMSampleTimingInfo)sampleTime
                 andSize:(CGSize)size
{

  if (!_assetWriter) {
    if (![self initializeAssetWriter]) {
      return;
    }
  }

  // convert CIImage to CMSampleBufferRef and save
  CGRect extent = [finalImage extent];
  CGFloat width = CGRectGetWidth(extent);
  CGFloat height  = CGRectGetHeight(extent);

  if ((width == 0) && (height == 0)) return;


  NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                           [NSDictionary dictionary], (id)kCVPixelBufferIOSurfacePropertiesKey,
                           @(YES), kCVPixelBufferCGImageCompatibilityKey,
                           @(YES), kCVPixelBufferCGBitmapContextCompatibilityKey,
                           kCVImageBufferYCbCrMatrix_ITU_R_601_4, kCVImageBufferYCbCrMatrixKey,
                           kCVImageBufferColorPrimaries_ITU_R_709_2, kCVImageBufferColorPrimariesKey, nil];

  // Initialize the video input if this is not done yet
  if (!_readyToWriteVideo) {
    _readyToWriteVideo = [self setupAssetWriterVideoInputWithSize:size];
  }

  CVPixelBufferRef pixelBuffer = NULL;

  CVPixelBufferCreate(kCFAllocatorSystemDefault, width, height, kCVPixelFormatType_32BGRA, (__bridge CFDictionaryRef) options, &pixelBuffer);

  CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
  [_ciContext render:finalImage toCVPixelBuffer:pixelBuffer];
  CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );

  CMVideoFormatDescriptionRef videoInfo = NULL;
  CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, &videoInfo);

  CMSampleBufferRef oBuf;
  OSStatus status = CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, true, NULL, NULL, videoInfo, &sampleTime, &oBuf);
  CVPixelBufferRelease(pixelBuffer);
  CFRelease(videoInfo);

  if (status != noErr) {
    NSLog(@"error creating CMSampleBufferCreateForImageBuffer");
    CFRelease(oBuf);
    return;
  }

  // Write video data to file only when all the inputs are ready
  if ([self inputsReadyToWriteToFile]) {
    if (_assetWriter.error) {
      NSLog(@"%@",[_assetWriter.error localizedDescription]);
      return;
    }
    [self writeSampleBuffer:oBuf ofType:AVMediaTypeVideo];
  }

  CFRelease(oBuf);

}


- (void)writeSampleBuffer:(CMSampleBufferRef)sampleBuffer ofType:(NSString *)mediaType
{  
  if ( _assetWriter.status == AVAssetWriterStatusUnknown ) {
    NSLog(@"unknown state");
    // If the asset writer status is unknown, implies writing hasn't started yet, hence start writing with start time as the buffer's presentation timestamp
    if ([_assetWriter startWriting]) {
      [_assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];
    } else {
          // error
     }
  }

  if ( _assetWriter.status == AVAssetWriterStatusWriting ) {
    // If the asset writer status is writing, append sample buffer to its corresponding asset writer input
    if (mediaType == AVMediaTypeVideo) {
      if (_assetWriterVideoInput.readyForMoreMediaData) {
        if (![_assetWriterVideoInput appendSampleBuffer:sampleBuffer]) {
          NSLog(@"error: %@", [_assetWriter.error localizedFailureReason]); //Ⓐ
        }
      }
    }
    else if (mediaType == AVMediaTypeAudio) {
      if (_assetWriterAudioInput.readyForMoreMediaData) {
        if (![_assetWriterAudioInput appendSampleBuffer:sampleBuffer]) {
                      // error
        }
      }
    }
  }

  if ( _assetWriter.status == AVAssetWriterStatusFailed ) {
    NSLog(@"error"); 
  }

}
这在iPadPro 9.7上运行得很好,但在iPad3上却很好Ⓐ, 在正确写入帧大约5秒钟后,失败得很惨

失败,错误为-536870211,这显然是未知错误

我已经检查了应用程序是否存在漏洞,但没有

有什么想法吗


注意:我现在发现,只有当我从后置摄像头(HD)写入帧时,问题才会显示出来。如果我切换到前置摄像头VGA(640x480),它可以正常工作。所以这与内存分配有关,但我已经检查过仪器和应用程序使用了大约12MB的内存,这个值或多或少是恒定的。无泄漏。

该错误是
kioreturnnomery

Memory can't be allocated (0xe00002bd).Value: 0xe00002bd (-536870211)
听起来你好像用了太多的内存。您需要确保在尽可能短的时间内保留尽可能少的样本缓冲区及其衍生物


仪器应用程序内存和GPU工具以及Xcode的内存仪表也应该有帮助。

我不知道。:)但我有一台iPad3。与iPad Pro相比,它是:(1)动力严重不足[frame Droping issue?](2)RAM内存高度受限(3)单核[threading issue?](4)32位[bitness issue?]好吧,我同意,但如果应用程序与iOS 9兼容,它就必须在iPad 3上运行。太棒了!首先,我要用我所有的仇恨感谢苹果。就像我经常说的,XCode是一堆燃烧的垃圾,应该被终止,苹果必须对开发者表现出一些爱。如果错误是已知的,什么样的病态开发团队决定抛出“未知错误”?第二,我说我只分配了一个样本缓冲区。第三,我想问你是怎么发现的?它将来可能有用。谢谢。我在谷歌上搜索了536870211,这证明了我的信念:处理内存限制是视频处理中最难的部分之一。另外,iPad3内存不足是出了名的。很抱歉再次打扰您,但是看看我的代码,您看到我可以做些什么来减少内存分配吗?谢谢你能创建一个可运行的项目吗?