AVAssetWriterInputPixelBufferAdaptor在init期间修改AVAssetWriterInput

时间:2014-05-20 22:36:08

标签: objective-c avfoundation avassetwriter

我遇到了一个奇怪的边缘情况,用AVAssetWriterInput初始化AVAssetWriterInputPixelBufferAdaptor会阻止AVAssetWriter使用相同的AVAssetWriterInput进行写入。仅当使用小于113的高度或宽度时才会发生这种情况。看起来AVAssetWriterInputPixelBufferAdaptor必须在其初始化程序期间修改AVAssetWriterInput。有什么想法吗?

这是一个解决问题的测试:

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

#define HEIGHT @100
#define WIDTH @100

@interface AVAssetWriterInput (dimensions)
+ (AVAssetWriterInput*)AVAssetWriterInputWithHeight: (NSNumber*) height width: (NSNumber*) width;
@end

@implementation AVAssetWriterInput (dimensions)
+ (AVAssetWriterInput*)AVAssetWriterInputWithHeight: (NSNumber*) height width: (NSNumber*) width{

    NSDictionary* cleanApertureSettings = @{AVVideoCleanApertureWidthKey : width,
                                            AVVideoCleanApertureHeightKey : height,
                                            AVVideoCleanApertureHorizontalOffsetKey : @0,
                                            AVVideoCleanApertureVerticalOffsetKey : @0};


    NSDictionary *videoCodecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithInt:1000000], AVVideoAverageBitRateKey,
                                        [NSNumber numberWithInt:1],AVVideoMaxKeyFrameIntervalKey,
                                        cleanApertureSettings, AVVideoCleanApertureKey,
                                        nil];

    NSDictionary *videoSettings = @{AVVideoCodecKey: AVVideoCodecH264,
                                    AVVideoCompressionPropertiesKey : videoCodecSettings,
                                    AVVideoWidthKey: width,
                                    AVVideoHeightKey: height
                                    };

    AVAssetWriterInput* input = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
                                               outputSettings:videoSettings];
    input.expectsMediaDataInRealTime = FALSE;
    return input;

}

@end

@interface AVAssetWriterInputTest : XCTestCase

@end

@implementation AVAssetWriterInputTest

- (void)setUp
{
    [super setUp];
}

- (void)tearDown
{
    [super tearDown];
}

- (BOOL) validAVAssetWriterStatus: (AVAssetWriterInput*) input{
    NSURL* outputURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"temp.mp4"]];

    NSError* writerError;
    AVAssetWriter * writer = [[AVAssetWriter alloc] initWithURL:outputURL fileType:AVFileTypeMPEG4 error:&writerError];
    XCTAssertNil(writerError);

    [writer addInput:input];
    [writer startWriting];
    BOOL validStatus = writer.status != AVAssetWriterStatusFailed;
    [writer cancelWriting];
    return validStatus;
}

//Succeeds
- (void)testDefaultCase{
    AVAssetWriterInput* input = [AVAssetWriterInput AVAssetWriterInputWithHeight:HEIGHT width:WIDTH];
    XCTAssertTrue([self validAVAssetWriterStatus:input], @"%@ x %@ default case fails", HEIGHT, WIDTH);
}

//Fails when height or width < 113
- (void)testWithAVAssetWriterInputPixelBufferAdaptor{
    AVAssetWriterInput* input = [AVAssetWriterInput AVAssetWriterInputWithHeight:HEIGHT width:WIDTH];

    NSDictionary* attributes = @{
                                 (NSString*)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32ARGB),
                                 (NSString*)kCVPixelBufferWidthKey : WIDTH,
                                 (NSString*)kCVPixelBufferHeightKey : HEIGHT,
                                 (NSString*)kCVPixelBufferCGImageCompatibilityKey : @YES,
                                 (NSString*)kCVPixelBufferCGBitmapContextCompatibilityKey : @YES
                                 };

    [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:input sourcePixelBufferAttributes:attributes];
    XCTAssertTrue([self validAVAssetWriterStatus:input], @"%@ x %@ adaptor case fails", HEIGHT, WIDTH);
}

@end

0 个答案:

没有答案