Я схожу с ума от этого - посмотрел повсюду и попробовал все, что только могу придумать.
Я создаю приложение для iPhone, которое использует AVFoundation - в частности, AVCapture для захвата видео с помощью камеры iPhone.
Мне нужно, чтобы пользовательское изображение накладывалось на видеопоток, включенный в запись.
Пока у меня настроен сеанс AVCapture, я могу отображать канал, получать доступ к кадру, сохранять его как UIImage и помечать наложенное изображение на него. Затем преобразуйте этот новый UIImage в CVPixelBufferRef. Чтобы проверить, работает ли bufferRef, я преобразовал его обратно в UIImage, и он все равно отображает изображение.
Проблема начинается, когда я пытаюсь преобразовать CVPixelBufferRef в CMSampleBufferRef для добавления к AVCaptureSessions assetWriterInput. CMSampleBufferRef всегда возвращает NULL, когда я пытаюсь его создать.
Вот функция - (void) captureOutput
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
UIImage *botImage = [self imageFromSampleBuffer:sampleBuffer];
UIImage *wheel = [self imageFromView:wheelView];
UIImage *finalImage = [self overlaidImage:botImage :wheel];
//[previewImage setImage:finalImage]; <- works -- the image is being merged into one UIImage
CVPixelBufferRef pixelBuffer = NULL;
CGImageRef cgImage = CGImageCreateCopy(finalImage.CGImage);
CFDataRef image = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));
int status = CVPixelBufferCreateWithBytes(NULL,
self.view.bounds.size.width,
self.view.bounds.size.height,
kCVPixelFormatType_32BGRA,
(void*)CFDataGetBytePtr(image),
CGImageGetBytesPerRow(cgImage),
NULL,
0,
NULL,
&pixelBuffer);
if(status == 0){
OSStatus result = 0;
CMVideoFormatDescriptionRef videoInfo = NULL;
result = CMVideoFormatDescriptionCreateForImageBuffer(NULL, pixelBuffer, &videoInfo);
NSParameterAssert(result == 0 && videoInfo != NULL);
CMSampleBufferRef myBuffer = NULL;
result = CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault,
pixelBuffer, true, NULL, NULL, videoInfo, NULL, &myBuffer);
NSParameterAssert(result == 0 && myBuffer != NULL);//always null :S
NSLog(@"Trying to append");
if (!CMSampleBufferDataIsReady(myBuffer)){
NSLog(@"sampleBuffer data is not ready");
return;
}
if (![assetWriterInput isReadyForMoreMediaData]){
NSLog(@"Not ready for data :(");
return;
}
if (![assetWriterInput appendSampleBuffer:myBuffer]){
NSLog(@"Failed to append pixel buffer");
}
}
}
Другое решение, о котором я продолжаю слышать, - это использование AVAssetWriterInputPixelBufferAdaptor, которое устраняет необходимость в беспорядочной упаковке CMSampleBufferRef. Тем не менее, я просмотрел форумы и документы разработчиков и не могу найти четкое описание или пример того, как это настроить или как его использовать. Если у кого-то есть работающий пример этого, не могли бы вы показать мне или помочь мне решить вышеупомянутую проблему - работали над этим безостановочно в течение недели, и я в конце концов.
Дайте мне знать, если вам нужна какая-либо другая информация
Заранее спасибо,
Michael