2017-03-27 7 views
2

私はこのカメラを作成しています。 iOS 9用に作成されているため、古いデバイスでテストする必要があります。その場合、iPadの3アプリはProの新しいiPad 9.7上で完璧に動作しますが、iPadの3で何が起こるiPad 3で約5秒間、ファイルにビデオを書き込むと失敗します。

に、しばらくして、ビデオの書き込みに失敗した、アプリが細かいフレームの書き込みを開始するが、突然失敗します。

は、私は、各フレームを保存するために、このメソッドを使用しています:

- (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"); 
    } 

} 

これはiPadのプロ9.7で正常に動作しますが、iPadの3で、それは約5秒間正しくフレームを書き込んだ後、無残に失敗し、ラインをⒶ当たります。

は明らかに不明なエラーでエラー-536870211、で失敗します。

私は漏れのアプリをチェックしていると、どれもありません。

アイデア?

注:私は、リアカメラ(HD)からフレームを書いていた場合に問題にのみ表示されることになりまし発見しました。私はフロントカメラのVGA(640×480)に切り替えると正常に動作します。だからそれはメモリの割り当てと関係がありますが、私は楽器でそれを確認して、アプリケーションは約12 MBのメモリを使用しており、この値はほぼ一定です。漏れはありません。

+0

私は分かりません。私はiPadの3を持っていますが、iPad Proと比較して、それは次のようなものです:(1)大量に[フレーム落ちの問題?](2)RAMメモリ(3) ](4)32ビット[bitness issue?] – matt

+0

ok私は同意しますが、アプリがiOS 9と互換性がある場合、iPad 3で実行する必要があります。 – SpaceDog

答えて

1

というエラーは、あなたがあまりにも多くのメモリを使用しているようなので、それが聞こえるkIOReturnNoMemory

Memory can't be allocated (0xe00002bd).Value: 0xe00002bd (-536870211) 

です。できるだけ短時間だけサンプルバッファーとその派生物をほとんど保持しないようにする必要があります。

楽器アプリのメモリとGPUツールとXcodeのメモリゲージがあまりにも助けになるはずです。

+0

Brilliant!まず第一に、私はアップルにすべての憎しみを感謝しなければならない。私がいつも言っているように、Xcodeは打ち切らなければならない炎のようなものだ.Appleは開発者に愛情を示す必要がある。どのような病気の開発チームは、エラーが分かっている場合は "未知のエラー"を投げることを決定?次に、私はただ1つのサンプルバッファを割り当てていると言います。第三に、あなたはどのようにそれを発見したのですか?将来的には役に立つかもしれません。感謝します。 – SpaceDog

+1

私はグーグル536870211メモリ制約を扱うことがビデオ処理の最も難しい部分の1つであると私の信念を裏付けました。また、iPad3はメモリ不足で悪名高いものでした。 –

+0

もう一度お悔やみしますが、自分のコードを見ると、メモリ割り当てを最小限に抑えるためにできることがありますか?ありがとう – SpaceDog