2011-12-15 107 views
3

我想使用AVFoundation框架从AVCaptureStillImageOutput快速捕获一系列静止图像,就像某些相机的突发模式。我想使用完成处理程序,保存CMSampleBufferRef供以后处理

[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection 
               completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 

并将imageSampleBuffer传递给NSOperation对象以供以后处理。但我无法找到一种方法来保留NSOperation类中的缓冲区。

[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection 
               completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 

    //Add to queue 
    SaveImageDataOperation *saveOperation = [[SaveImageDataOperation alloc] initWithImageBuffer:imageSampleBuffer]; 
    [_saveDataQueue addOperation:saveOperation]; 
    [saveOperation release]; 

    //Continue 
    [self captureCompleted]; 
}]; 

有没有人知道我在这里做错了什么?有没有更好的方法来做到这一点?

回答

7

“重要提示:即使在使用垃圾回收的进程中,CMSampleBuffer的客户端也必须通过调用CFRetain和CFRelease显式管理保留计数。”

来源:CoreMedia.Framework CMSampleBuffer.h

0

我已经做了很多与CMSampleBuffer工作的对象,最近,我已经了解到,大部分在实时操作由OS源媒体缓冲区是从池中分配。如果AVFoundation(或CoreVideo/CoreMedia)耗尽了池中的缓冲区(也就是说CFR在很长的时间内保留一个缓冲区),则进程的实时方面将会受到影响或阻塞,直到您将CF释放回缓冲区游泳池。

因此,除了操纵CMSampleBuffer上的CFRetain/CFRelease计数,您应该只保留足够长的缓冲区以解压CMBlockBuffer/CMFormat并创建一个新的CMSampleBuffer以传递到您的NSOperationQueue或dispatch_queue_t供以后处理。

在我的情况下,我想通过网络从VideoToolbox传递压缩的CMSampleBuffers。我基本上创建了一个CMSampleBuffer的深层副本,我的应用程序可以完全控制内存分配/生存期。从那里,我将复制的CMSampleBuffer放在一个队列中供网络I/O使用。

如果样本数据被压缩,深度复制应该相对较快。在我的应用程序中,我使用NSKeyedArchiver从源CMSampleBuffer的相关部分创建NSData对象。对于H.264视频数据,这意味着CMBlockBuffer内容,SPS/PPS头字节以及SampleTimingInfo。通过对这些元素进行序列化,我可以在网络的另一端重建一个CMSampleBuffer,它的行为与VideoToolbox给我的相同。特别是,AVSampleBufferLayer能够显示它们,就好像它们本机来源于机器。

为您的应用我想提出以下建议:

  1. 把你的源CMSampleBuffer和压缩的像素数据。如果您可以使用VideoToolbox中的硬件编码器仅创建I-帧 H.264图像质量非常高。 VT编码器 显然非常适合电池使用时间,可能比JPEG要好很多,除非它们在 系统上也有硬件JPEG编解码器。
  2. 将压缩的CMSampleBuffer输出深度拷贝 VideoToolbox,VT将CF释放原始CMSampleBuffer返回 到捕获子系统使用的池。
  3. 保留VT压缩的CMSampleBuffer的时间足够长,以便排入深层副本以供日后处理。

由于AVFoundation电影记录可以做的步骤#1和#2实时不会耗尽缓冲区,你应该能够深拷贝和排队上dispatch_queue您的数据,而无需耗尽由所使用的缓冲池视频捕获组件和VideoToolbox组件。

相关问题