对于高位深度缓冲区,M1 Max上的ProRes编码失败



我的代码已经为编写ProRes文件工作了很多年,现在它在新的M1 Max MacBook上失败了。具体地说,如果我构造具有像素类型"0"的缓冲器;CCD_ 1";,在写入几帧之后,追加操作失败,并出现错误-12905。这表示写入系统无法对此缓冲区类型进行转换,这是非常奇怪和意外的行为。同样,这段代码在非Max处理器上运行得很好(英特尔和M1本身(。这里有一个示例main来演示这个问题。我是不是做错了什么?

//
//  main.m
//  TestProresWriting
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
int timescale = 24;
int width = 1920;
int height = 1080;
NSURL *url = [NSURL fileURLWithPath:@"/Users/diftil/TempData/testfile.mov"];

NSLog(@"Output file = %@", [url absoluteURL]);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
[fileManager removeItemAtURL:url error:&error];

// Set up the writer
AVAssetWriter *trackWriter =
[[AVAssetWriter alloc] initWithURL:url
fileType:AVFileTypeQuickTimeMovie
error:&error];

// Set up the track
NSDictionary *videoSettings =
@{AVVideoCodecKey: AVVideoCodecTypeAppleProRes4444,
AVVideoWidthKey: @(width),
AVVideoHeightKey: @(height)};

AVAssetWriterInput *track =
[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];

// Set up the adapter
// This pixel type causes problems on M1 Max
NSDictionary *attributes =
@{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_64ARGB),
(id)kCVPixelBufferWidthKey: @(width),
(id)kCVPixelBufferHeightKey: @(height)};

// This pixel type works on M1 Max
//  NSDictionary *attributes =
//      @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32ARGB),
//        (id)kCVPixelBufferWidthKey: @(width),
//        (id)kCVPixelBufferHeightKey: @(height)};

AVAssetWriterInputPixelBufferAdaptor *pixelBufferAdaptor =
[AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:track
sourcePixelBufferAttributes:attributes];

// Add the track and start writing
[trackWriter addInput:track];
[trackWriter startWriting];

CMTime startTime = CMTimeMake(0, timescale);
[trackWriter startSessionAtSourceTime:startTime];

while(!track.readyForMoreMediaData);

CVPixelBufferRef frameBuffer = NULL;

for (int i = 0; i < 100; i++)
{
NSLog(@"Frame %d", i);
CVPixelBufferPoolRef PixelBufferPool = pixelBufferAdaptor.pixelBufferPool;
if (PixelBufferPool == nil)
{
NSLog(@"PixelBufferPool is invalid.");
exit(1);
}
CVReturn ret = CVPixelBufferPoolCreatePixelBuffer(nil, PixelBufferPool,
&frameBuffer);
if (ret != kCVReturnSuccess)
{
NSLog(@"Error creating framebuffer from pool");
exit(1);
}

CVPixelBufferLockBaseAddress(frameBuffer, 0);
void *imagebuf = CVPixelBufferGetBaseAddress(frameBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(frameBuffer);
memset(imagebuf, 0x00, bytesPerRow * height);
CVPixelBufferUnlockBaseAddress(frameBuffer, 0);

while(!track.readyForMoreMediaData);

CMTime presentationTime = CMTimeMake(i, timescale);
BOOL result = [pixelBufferAdaptor appendPixelBuffer:frameBuffer
withPresentationTime:presentationTime];
if (result == NO)
{
NSLog(@"Error appending to track.");
NSError *error = trackWriter.error;
if(error!=nil) {
NSLog(@"Unresolved error %@,%@.", error, [error userInfo]);
}
exit(1);

}

CVPixelBufferRelease(frameBuffer);
}

// Close everything
if ( trackWriter.status == AVAssetWriterStatusWriting)
[track markAsFinished];
__block BOOL isOpen = YES;
[trackWriter finishWritingWithCompletionHandler:^{
isOpen = NO;
NSLog(@"Closed.");
}];
while (isOpen);

NSLog(@"Completed.");
}
return 0;
}

运行此代码将产生:

2021-11-13 14:11:37.032427-0700 TestProresWriting[56235:2066349] Output file = file:///Users/diftil/TempData/testfile.mov
2021-11-13 14:11:37.054946-0700 TestProresWriting[56235:2066349] Metal API Validation Enabled
2021-11-13 14:11:37.155398-0700 TestProresWriting[56235:2066349] Frame 0
2021-11-13 14:11:37.158434-0700 TestProresWriting[56235:2066349] Frame 1
2021-11-13 14:11:37.158607-0700 TestProresWriting[56235:2066349] Frame 2
2021-11-13 14:11:37.158715-0700 TestProresWriting[56235:2066349] Frame 3
2021-11-13 14:11:37.159803-0700 TestProresWriting[56235:2066349] Frame 4
2021-11-13 14:11:37.172890-0700 TestProresWriting[56235:2066349] Frame 5
2021-11-13 14:11:37.176622-0700 TestProresWriting[56235:2066349] Error appending to track.
2021-11-13 14:11:37.176723-0700 TestProresWriting[56235:2066349] Unresolved error Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-12905), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x10602c1e0 {Error Domain=NSOSStatusErrorDomain Code=-12905 "(null)"}},{
NSLocalizedDescription = "The operation could not be completed";
NSLocalizedFailureReason = "An unknown error occurred (-12905)";
NSUnderlyingError = "Error Domain=NSOSStatusErrorDomain Code=-12905 "(null)"";
}.
Program ended with exit code: 1

如果我将kCVPixelFormatType_64ARGB更改为kCVPixelFormatType_32ARGB,它在我的带有M1 Max的MacBook Pro上运行良好。同样,原始代码在其他所有计算机上都运行良好。

这原来是苹果的一个错误,在MacOS 13(Ventura(中修复了这个错误。这与在Pro和Max M系列硅上处理ProRes有关。现在没有问题!

最新更新