AVSampleBufferDisplayLayer does not render content

Originator:kevin
Number:rdar://27476998 Date Originated:2016-07-21
Status:Closed Resolved:Yes
Product:iOS Product Version:iOS 10.0 [14A5309d]
Classification:Bug Reproducible:Always
 
This issue resolved in iOS 10 Beta 4 [14A5322e].

Area:
AVFoundation (Audio / Video)

Summary:
AVSampleBufferDisplayLayer does not display an IOSurface-backed CVPixelBufferRef (kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) on iOS 10.

Steps to Reproduce:
Launch the demo attached. Important sample code is in ViewController.m
1) Create a CVPixelBufferRef backed by an IOSurface (kCVPixelBufferIOSurfacePropertiesKey attribute)
2) Wrap that pixel buffer in a CMSampleBufferRef with settings for immediate display
3) Enqueue the sample buffer in an AVSampleBufferDisplayLayer

Expected Results:
On iOS 9 and earlier, this displays the pixel buffer content (centered green screen in the sample app).

Actual Results:
On iOS 10 the layer appears completely transparent.

Version:
iOS 10.0 [14A5309d]

Notes:
Relevant code is in the -displayTestBuffer method in ViewController.m.

Compiling with Xcode 7.3.x (iOS 9 SDK) vs 8.0 (iOS 10 SDK) does not seem to have any effect. Using direct allocation for the buffer vs using a buffer pool also does not seem to have any effect.

Configuration:
iPhone 6, 64GB, AT&T and various others


Excerpt from sample code submitted with report:
===================

@import AVFoundation;
@import UIKit;
@import CoreVideo;

@interface SampleBufferView : UIView
@property (nonatomic, readonly) AVSampleBufferDisplayLayer *sampleBufferDisplayLayer;
@end

@implementation SampleBufferView
+ (Class)layerClass {
    return [AVSampleBufferDisplayLayer class];
}
- (AVSampleBufferDisplayLayer *)sampleBufferDisplayLayer {
    return (AVSampleBufferDisplayLayer *)self.layer;
}
@end

@interface ViewController : UIViewController
@end

@interface ViewController ()
@property (nonatomic, readonly) SampleBufferView *sampleBufferView;
@end

@implementation ViewController

- (void)loadView {
    self.view = [SampleBufferView new];
}

- (SampleBufferView *)sampleBufferView {
    return (SampleBufferView *)self.view;
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    [self displayTestBuffer];
}

- (void)displayTestBuffer {
    
    NSDictionary *attributes = @{ (id)kCVPixelBufferIOSurfacePropertiesKey: @{} };
    
    CVPixelBufferRef pixelBuffer;
    if (CVPixelBufferCreate(kCFAllocatorDefault,
                            1920,
                            1080,
                            kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
                            (__bridge CFDictionaryRef)attributes,
                            &pixelBuffer) != kCVReturnSuccess) {
        [NSException raise:NSInternalInconsistencyException
                    format:@"Failure in CVPixelBufferCreate"];
        return;
    }
    
    CMVideoFormatDescriptionRef formatDescription;
    if (CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault,
                                                     pixelBuffer,
                                                     &formatDescription) != noErr) {
        [NSException raise:NSInternalInconsistencyException
                    format:@"Failure in CMVideoFormatDescriptionCreateForImageBuffer"];
        return;
    }
    
    CMSampleBufferRef sampleBuffer;
    if (CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault,
                                                 pixelBuffer,
                                                 formatDescription,
                                                 &kCMTimingInfoInvalid,
                                                 &sampleBuffer) != noErr) {
        [NSException raise:NSInternalInconsistencyException
                    format:@"Failure in CMSampleBufferCreateReadyWithImageBuffer"];
        return;
    }
    
    CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, true);
    CFMutableDictionaryRef attachments = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachmentsArray, 0);
    
    CFDictionarySetValue(attachments, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);
    
    
    [self.sampleBufferView.sampleBufferDisplayLayer enqueueSampleBuffer:sampleBuffer];
    
    CVPixelBufferRelease(pixelBuffer);
    CFRelease(formatDescription);
    CFRelease(sampleBuffer);
}

@end

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!