AVSampleBufferDisplayLayer不再在iOS10中渲染帧

时间:2016-07-14 02:41:36

标签: avfoundation calayer ios10

在iOS10之前,以下设置一直在处理所有最近的iOS版本:

我正在使用AVSampleBufferDisplayLayer从自定义源渲染原始帧。

我使用CVPixelBufferPoolCreate设置了像素缓冲池,并按照Apple的指示将kCVPixelBufferIOSurfacePropertiesKey设置为@{}

我使用CVPixelBufferPoolCreatePixelBuffer从池中获取像素缓冲区,然后使用CVPixelBufferLockBaseAddressCVPixelBufferUnlockBaseAddress将我的数据复制到缓冲区。

我的原始帧使用NV12格式kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange

这是一段代码片段,展示了如何将像素缓冲区转换为CMSampleBufferRef并将其排入显示层:

  CMSampleTimingInfo sampleTimeinfo{
      CMTimeMake(duration.count(), kOneSecond.count()),
      kCMTimeInvalid,
      kCMTimeInvalid};

  CMFormatDescriptionRef formatDescription = nullptr;
  CMVideoFormatDescriptionCreateForImageBuffer(nullptr, pixelBuffer, &formatDescription);

  CMSampleBufferRef sampleBuffer = nullptr;
  CMSampleBufferCreateForImageBuffer(
          nullptr, pixelBuffer, true, nullptr, nullptr, formatDescription, &sampleTimeinfo, &sampleBuffer));


  CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, YES);
  const CFIndex numElementsInArray = CFArrayGetCount(attachmentsArray);

  for (CFIndex i = 0; i < numElementsInArray; ++i) {
    CFMutableDictionaryRef attachments = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachmentsArray, i);
    CFDictionarySetValue(attachments, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);
  }

  if ([avfDisplayLayer_ isReadyForMoreMediaData]) {
    [avfDisplayLayer_ enqueueSampleBuffer:sampleBuffer];
  }

  CFRelease(sampleBuffer);
  CFRelease(formatDescription);

pixelBuffer的类型为CVPixelBufferRefavfDisplayLayer_ AVSampleBufferDisplayLayer

下一个片段展示了我如何构建显示层:

  avfDisplayLayer_ = [[AVSampleBufferDisplayLayer alloc] init];
  avfDisplayLayer_.videoGravity = AVLayerVideoGravityResizeAspectFill;

我没有收到任何警告或错误消息,显示图层状态不表示失败,isReadyForMoreMediaData返回true。

问题是我的画面没有显示在屏幕上。我还在显示层上设置了背景颜色,只是为了确保图层合成正确(就是这样)。

关于AVSampleBufferDisplayLayer,iOS10中的某些内容必须有所改变,但我无法弄清楚它是什么。

1 个答案:

答案 0 :(得分:1)

事实证明,使用iOS10时,CMSampleTimingInfo的值显然会被更严格地解析。

以上代码更改为以下代码,以使渲染再次正常工作:

  CMSampleTimingInfo sampleTimeinfo{
      CMTimeMake(duration.count(), kOneSecond.count()),
      kCMTimeZero,
      kCMTimeInvalid};

请注意kCMTimeZero字段的presentationTimeStamp

@Sterling Archer:您可能想尝试一下,看看它是否也能解决您的问题。