AVPlayerItemVideoOutput永远不会获得pixelBuffer

时间:2017-02-16 11:29:27

标签: ios objective-c unit-testing opengl-es avfoundation

我一直在扩展我对视频渲染代码的测试,并在使用AVPlayerItemVideoOutput进行测试时发现了一些异常。在尝试测试我的渲染代码时,我使用hasNewPixelBufferForItemTime检查新的像素缓冲区。

测试时,此方法永远不会返回yes。但是渲染代码可以在我的应用程序中使用相同的设置,将帧渲染为openGL纹理。

我设置了一个github项目,其中包含显示错误的基础知识。在应用程序中,您可以通过点击按钮加载视频(不立即加载以避免与测试发生任何冲突)。这至少证明了视频的加载和播放。

该项目还有测试,尝试设置AVPlayerItemVideoOutput并检查新的像素缓冲区。此测试总是失败,但我无法看到我做错了什么,或者为什么完全相同的步骤在我自己的应用中有效。

The GitHub project is here

这是仔细阅读的测试方法:

#import <XCTest/XCTest.h>
#import <AVFoundation/AVFoundation.h>

@interface AVPlayerTestTests : XCTestCase

@end

@implementation AVPlayerTestTests

- (void)setUp {
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

- (void) testAVPlayer
{
    NSURL *fileURL = [[NSBundle bundleForClass:self.class] URLForResource:@"SampleVideo_1280x720_10mb" withExtension:@"mp4"];
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:fileURL];
    [self keyValueObservingExpectationForObject:playerItem
                                        keyPath:@"status" handler:^BOOL(id  _Nonnull observedObject, NSDictionary * _Nonnull change) {
                                            AVPlayerItem *oPlayerItem = (AVPlayerItem *)observedObject;
                                            switch (oPlayerItem.status) {
                                                case AVPlayerItemStatusFailed:
                                                {
                                                    XCTFail(@"Video failed");
                                                    return YES;
                                                }
                                                    break;
                                                case AVPlayerItemStatusUnknown:
                                                    return NO;
                                                    break;
                                                    case AVPlayerItemStatusReadyToPlay:
                                                {
                                                    return YES;
                                                }
                                                default:
                                                    break;
                                            }
                                        }];
    AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
    NSDictionary *pbOptions = @{
                                (NSString *)kCVPixelBufferPixelFormatTypeKey        : [NSNumber numberWithInt:kCVPixelFormatType_32BGRA],
                                (NSString *)kCVPixelBufferIOSurfacePropertiesKey    : [NSDictionary dictionary],
                                (NSString *)kCVPixelBufferOpenGLESCompatibilityKey  : @YES
                                };
    AVPlayerItemVideoOutput *output = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pbOptions];
    XCTAssertNotNil(output);
    [self waitForExpectationsWithTimeout:100 handler:nil];
    if (playerItem.status == AVPlayerItemStatusReadyToPlay) {
        [playerItem addOutput:output];
        player.rate = 1.0;
        player.muted = YES;
        [player play];
        CMTime vTime = [output itemTimeForHostTime:CACurrentMediaTime()];
        // This is what we're testing
        BOOL foundFrame = [output hasNewPixelBufferForItemTime:vTime];
        XCTAssertTrue(foundFrame);
        if (!foundFrame) {
            // Cycle over for ten seconds
            for (int i = 0; i < 10; i++) {
                sleep(1);
                vTime = [output itemTimeForHostTime:CACurrentMediaTime()];
                foundFrame = [output hasNewPixelBufferForItemTime:vTime];
                if (foundFrame) {
                    NSLog(@"Got frame at %i", i);
                    break;
                }
                if (i == 9) {
                    XCTFail(@"Failed to acquire");
                }
            }
        }

    }
}


@end

编辑1:这似乎是一个错误,我已经提交了雷达

0 个答案:

没有答案