Я разрабатываю приложение для создания фильмов, которое влияет на импортированные видео. Я использую AVAssetWriter для кодирования своего приложения. Все работает очень хорошо, но у меня большая проблема в памяти. Мое приложение занимает более 500 МБ оперативной памяти в процессе буферизации. Просто алгоритм для создания отфильтрованного видео выглядит следующим образом:CGContextDrawImage огромный пик памяти
1- импорт видео.
2. Извлеките все кадры для видео как объекты CMSampleBuffer.
3- преобразовать объект CMSampleBuffer в uiimage.
4- внедрить фильтр на устройстве uiimage.
5- преобразовать uiimage обратно в новый объект CMSAmpleBuffer.
6- Добавить новый буфер в выход для записи.
7- Наконец, сохраните новый фильм в PhotoGallery.
Проблема заключается в STEP5 У меня есть функция, которая преобразует UIImage в cvpixelBuffer объекта и вернуть его. Затем я конвертирую объект CVPixelBuffer в CMSampleBuffer. Функция увеличивает объем памяти, и приложение заканчивается в конце.
Это мой код:
-(CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image andSize:(CGSize)size
{
double height = CGImageGetHeight(image);
double width = CGImageGetWidth(image);
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, size.width,
size.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,
&pxbuffer);
if (status != kCVReturnSuccess) {
return NULL;
}
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata,size.width ,
size.height, 8, 4*size.width, rgbColorSpace,
kCGImageAlphaNoneSkipFirst);
CGFloat Y ;
if (height == size.height)
Y = 0;
else
Y = (size.height /2) - (height/2) ;
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(0, Y,width,height), image);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
CGContextDrawImage увеличивает память 2 ~ 5 МБ на преобразование кадров.
Я попытался следующие решения:
1- рилизинг pxbuffer использованием CFRelease.
2- Я использовал CGImageRelease, чтобы снять изображение ref.
3- Я окружил код @autoreleasepool блок.
4- Я использовал CGContextRelease.
5- UIGraphicsEndImageContext.
6- Использовал Analyse тоже в Xcode и зафиксировал все точки.
Вот полный код для фильтрации видео:
- (void)assetFilteringMethod:(FilterType)filterType AndAssetURL:(NSURL *)assetURL{
CMSampleBufferRef sbuff ;
[areader addOutput:rout];
[areader startReading];
UIImage* bufferedImage;
while ([areader status] != AVAssetReaderStatusCompleted) {
sbuff = [rout copyNextSampleBuffer];
if (sbuff == nil)
[areader cancelReading];
else{
if (writerInput.readyForMoreMediaData) {
@autoreleasepool {
bufferedImage = [self imageFromSampleBuffer:sbuff];
bufferedImage = [FrameFilterClass convertImageToFilterWithFilterType:filterType andImage: bufferedImage];
CVPixelBufferRef buffer = NULL;
buffer = [self pixelBufferFromCGImage:[bufferedImage CGImage] andSize:CGSizeMake(320,240)];
[adaptor appendPixelBuffer:buffer withPresentationTime:CMSampleBufferGetPresentationTimeStamp(sbuff)];
CFRelease(buffer);
CFRelease(sbuff);
}
}
}
}
//Finished buffering
[videoWriter finishWritingWithCompletionHandler:^{
if (videoWriter.status != AVAssetWriterStatusFailed && videoWriter.status == AVAssetWriterStatusCompleted){
dispatch_async(dispatch_get_main_queue(), ^{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([library
videoAtPathIsCompatibleWithSavedPhotosAlbum:[NSURL fileURLWithPath:moviePath]]) {
[library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:moviePath]
completionBlock:^(NSURL *assetURL, NSError *error){
}];
}
});
}
else
NSLog(@"Video writing failed: %@", videoWriter.error);
}];
}
я провел около 3 до 4 дней, пытаясь решить эту проблему ... Любая помощь будет оценена.
WOW это сработало, Thankssssss! – user3125119