У меня возникают проблемы с тем, чтобы цвета визуализированного видео соответствовали цветам исходного содержимого. Я визуализирую изображения в CGContext, конвертирую данные резервного копирования в CVPixelBuffer и добавляю их как фрейм в AVAssetWriterInputPixelBufferAdaptor. Это вызывает небольшие различия в цвете между изображениями, которые я рисую в CGContext, и результирующим видеофайлом.
Похоже, есть 3 вещи, которые необходимо решить:
- сообщить AVFoundation, в каком цветовом пространстве находится видео.
- сделайте так, чтобы AVAssetWriterInputPixelBufferAdaptor и CVPixelBuffers, которые я добавляю к нему, соответствовали этому цветовому пространству.
- используйте то же цветовое пространство для CGContext.
Документация ужасна, поэтому я был бы признателен за любые советы о том, как это сделать, или если есть что-то еще, что мне нужно сделать, чтобы сохранить цвета на протяжении всего этого процесса.
Полный код:
AVAssetWriter *_assetWriter;
AVAssetWriterInput *_assetInput;
AVAssetWriterInputPixelBufferAdaptor *_assetInputAdaptor;
NSDictionary *outputSettings = @{ AVVideoCodecKey :AVVideoCodecH264,
AVVideoWidthKey :@(outputWidth),
AVVideoHeightKey:@(outputHeight)};
_assetInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:outputSettings];
NSDictionary *bufferAttributes = @{å(NSString*)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32ARGB)};
_assetInputAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:_assetInput
sourcePixelBufferAttributes:bufferAttributes];
_assetWriter = [AVAssetWriter assetWriterWithURL:aURL fileType:AVFileTypeMPEG4 error:nil];
[_assetWriter addInput:_assetInput];
[_assetWriter startWriting];
[_assetWriter startSessionAtSourceTime:kCMTimeZero];
NSInteger bytesPerRow = outputWidth * 4;
long size = bytesPerRow * outputHeight;
CGColorSpaceRef srgbSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
UInt8 *data = (UInt8 *)calloc(size, 1);
CGContextRef ctx = CGBitmapContextCreateWithData(data, outputWidth, outputHeight, 8, bytesPerRow, srgbSpace, kCGImageAlphaPremultipliedFirst, NULL, NULL);
// draw everything into ctx
CVPixelBufferRef pixelBuffer;
CVPixelBufferCreateWithBytes(kCFAllocatorSystemDefault,
outputWidth, outputHeight,
k32ARGBPixelFormat,
data,
bytesPerRow,
ReleaseCVPixelBufferForCVPixelBufferCreateWithBytes,
NULL,
NULL,
&pixelBuffer);
NSDictionary *pbAttachements = @{(id)kCVImageBufferCGColorSpaceKey : (__bridge id)srgbSpace};
CVBufferSetAttachments(pixelBuffer, (__bridge CFDictionaryRef)pbAttachements, kCVAttachmentMode_ShouldPropagate);
[_assetInputAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:CMTimeMake(0, 60)];
CGColorSpaceRelease(srgbSpace);
[_assetInput markAsFinished];
[_assetWriter finishWritingWithCompletionHandler:^{}];