2017-04-10 48 views
1

我有这款相机的应用程序。为什么一个方法可以很好地工作,但如果我把它放在dispatch_async里面会崩溃?

我把图像从相机,并处理与过滤器,并在里面captureOutput:didOutputSampleBuffer:fromConnection:某些时候,我把最后的图像,并利用这一点,写入文件:奇妙

CFRetain(sampleBuffer); 
    [myself writeToVideoImage:resultadoFinal 
      withSampleBuffer:sampleBuffer]; 
    CFRelease(sampleBuffer); 

作品,但如果我把这个队列内,像这样:

CFRetain(sampleBuffer);   
    dispatch_async(_writeToVideoQueue, ^{ 
     [myself writeToVideoImage:resultadoFinal 
       withSampleBuffer:sampleBuffer]; 
     CFRelease(sampleBuffer); 
    }); 

崩溃就行

[_assetWriter startSessionAtSourceTime:presentationTime]; 

of

- (void)writeToVideoImage:(CIImage *)resultadoFinal 
     withSampleBuffer:(CMSampleBufferRef)sampleBuffer 
{ 

    CFRetain(sampleBuffer); 
    CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); 

    CGRect extent = [resultadoFinal extent]; 

    if (!_readyToWriteVideo) { 
    _readyToWriteVideo = [self setupAssetWriterVideoInputWithSize:extent.size]; 
    return; 
    } 
    else if (_videoWritingStarted) { 
    _videoWritingStarted = NO; 
    // ***** CRASHES HERE ************ 
    [_assetWriter startSessionAtSourceTime:presentationTime]; 
    } 


    CVPixelBufferRef renderedOutputPixelBuffer = NULL; 

    OSStatus err = CVPixelBufferPoolCreatePixelBuffer(NULL, 
                _pixelBufferAdaptor.pixelBufferPool, 
                &renderedOutputPixelBuffer); 
    if (err) return; 

    [_ciContext render:resultadoFinal 
    toCVPixelBuffer:renderedOutputPixelBuffer 
       bounds:extent 
      colorSpace:_sDeviceRgbColorSpace]; 

    [self writeToFile:renderedOutputPixelBuffer 
     comSampleTime:presentationTime 
       size:extent.size]; 
    CFRelease(renderedOutputPixelBuffer); 
    CFRelease(sampleBuffer); 
} 

我不知道发生了什么。

它似乎是一些释放。我第一次怀疑sampleBuffer正在释放,但我保留它的功能内外,以防万一。我也尝试在调用方法之前在块内创建resultadoFinal的副本,但没有成功。

Xcode中显示错误

[AVAssetWriter startSessionAtSourceTime:]不能调用方法时的状态是0

大约有上做题。我尝试了所有建议,但都没有成功。

任何想法?

+1

听起来好像你在分派写入之后,但在执行之前对资产编写者做了某些事情(我知道这是模糊的)。暴力方法可能是观察“状态”(KVO)并查看是否有东西将其改变为被拒绝的值。 –

+1

我对AVAssetWriter了解不多,但是错误“状态为0时无法调用方法”听起来像某些东西没有正确初始化 - 请记住,当您在不同线程上运行dispatch_async时,可能需要某些东西在该线程上初始化?只是一个想法 –

+0

@JeffLoughlin - 简直太棒了!我使用了3个队列,一个以超高优先级在屏幕上显示视频,另一个以高优先级将帧写入磁盘,另一个以中等优先级来执行其他操作。这种做法是最近发生的,错误的是'AVAssetWriter'初始化发生在另一个队列上,而不是正在编写视频的队列。现在它像丝一样工作。谢谢!请将此评论作为答案,以便我可以接受。 – SpaceDog

回答

1

错误“状态为0时无法调用方法”听起来像某些东西没有正确初始化 - 请记住,当您在不同线程上运行dispatch_async时,所以您需要在该线程上初始化AVAssetWriter。

+0

只是灿烂的!我使用了3个队列,一个以超高优先级在屏幕上显示视频,另一个以高优先级将帧写入磁盘,另一个以中等优先级来执行其他操作。这种方法是最近的错误,AVAssetWriter初始化发生在另一个队列上,而不是正在编写视频的队列。现在它像丝一样工作。谢谢! – SpaceDog

+0

我不知道“辉煌”是如何描述我的答案......就像我上面所说,我对AVAssetWriter了解不多,所以这只是一个猜测 - 但我一直在围绕这个iOS足够长的时间来识别一些常见问题以及遇到它们时出现的错误类型(它们并不总是清楚说明实际问题是什么......)。很高兴我能帮上忙。 –

相关问题