菜鸟教程小白 发表于 2022-12-13 12:59:22

ios - AVSampleBufferDisplayLayer 不在设备上呈现


                                            <p><p>我在 iOS 上使用 AVSampleBufferDisplayLayer 时遇到了困难。我想使用这个层显示一个 CVPixelBuffer,但我无法让它在实际的 iOS 设备上工作。在我的示例应用程序中,我尝试使用以下代码来显示一种颜色像素缓冲区:</p>

<pre><code>@implementation ViewController {
    AVSampleBufferDisplayLayer *videoLayer;
}

- (void)viewDidLoad {
    ;

    videoLayer = [ init];
    videoLayer.frame = CGRectMake(50, 50, 300, 300);
    videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    ;
}

@implementation ViewController {
    AVSampleBufferDisplayLayer *videoLayer;
}

- (void)viewDidLoad {
    ;

    videoLayer = [ init];
    videoLayer.frame = CGRectMake(50, 50, 300, 300);
    videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    ;
}

- (void)viewDidAppear:(BOOL)animated {
    ;
    ;
}

- (void)startVideo {
    ;
    ;
}

- (void)drawPixelBuffer {

    int imageSize = 100;

    static const uint8_t pixel[] = {0x00, 0xAA, 0xFF, 0xFF};

    NSMutableData *frame = ;

    for (int i = 0; i &lt; imageSize * imageSize; i++) {
      ;
    }

    CVPixelBufferRef pixelBuffer = NULL;

    CVPixelBufferCreateWithBytes(NULL, imageSize, imageSize, kCVPixelFormatType_32BGRA, , imageSize * 4, NULL, NULL, NULL, &amp;pixelBuffer);

    CMSampleBufferRef sampleBuffer = ;

    if (sampleBuffer) {

      ;
      CFRelease(sampleBuffer);

    }

}

- (CMSampleBufferRef)sampleBufferFromPixelBuffer:(CVPixelBufferRef)pixelBuffer {

    CMSampleBufferRef sampleBuffer = NULL;
    OSStatus err = noErr;
    CMVideoFormatDescriptionRef formatDesc = NULL;
    err = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, &amp;formatDesc);

    if (err != noErr) {
      return nil;
    }

    CMSampleTimingInfo sampleTimingInfo = kCMTimingInfoInvalid;

    err = CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, pixelBuffer, formatDesc, &amp;sampleTimingInfo, &amp;sampleBuffer);

    if (sampleBuffer) {
      CFArrayRef attachments = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, YES);
      CFMutableDictionaryRef dict = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachments, 0);
      CFDictionarySetValue(dict, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);
    }

    if (err != noErr) {
      return nil;
    }

    formatDesc = NULL;

    return sampleBuffer;

}

@end
</code></pre>

<p>这在 iOS 模拟器中运行没有任何问题,但在真实设备上无法运行(没有渲染)。视频层的错误属性始终为 nil,状态始终等于 AVQueuedSampleBufferRenderingStatusRendering。</p>

<p>感谢您的帮助。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>模拟器中的图形实现要健壮得多,而且您通常可以摆脱在设备上无法运行的东西。常见的原因有两种:</p>

<h3>像素缓冲区应该由 IOSurface 支持</h3>

<p>您正在通过 <code>CVPixelBufferCreateWithBytes</code> 直接映射该缓冲区。再次尝试使用 <code>CVPixelBufferCreate</code> 并将 <code>kCVPixelBufferIOSurfacePropertiesKey</code> 属性设置为空字典。</p>

<pre><code>CVPixelBufferCreate(
    NULL,
    imageSize,
    imageSize,
    kCVPixelFormatType_32BGRA,
    (__bridge CFDictionaryRef)@{
      (id)kCVPixelBufferIOSurfacePropertiesKey: @{}
    },
    &amp;pixelBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
void *bytes = CVPixelBufferGetBaseAddress(pixelBuffer);
// Write image data directly to that address
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
</code></pre>

<p>实际上,任何生成这些像素的东西都应该尽可能直接写入 <code>CVPixelBufferRef</code>。</p>

<h3>设备不支持某些格式</h3>

<p>这对于 <code>kCVPixelFormatType_32BGRA</code> 来说似乎极不可能,但我已经看到了仅模拟器支持,例如 <code>kCVPixelFormatType_422YpCbCr8</code>。在这些情况下,必须首先将其转换为兼容格式,或者必须实现自定义渲染器(OpenGL、Metal 等)。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - AVSampleBufferDisplayLayer 不在设备上呈现,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/35365008/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/35365008/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - AVSampleBufferDisplayLayer 不在设备上呈现