iPhone中的video过滤速度很慢

我正在尝试在iPhone中过滤video。 这是我的程序结构和源代码:

AppDelegate.h AppDelegate.m ViewController.h ViewController.m 

AppDelegate文件与默认文件相同。 这是我的ViewController。

 //ViewController.h #import <UIKit/UIKit.h> #import <GLKit/GLKit.h> #import <AVFoundation/AVFoundation.h> #import <CoreMedia/CoreMedia.h> #import <CoreVideo/CoreVideo.h> #import <QuartzCore/QuartzCore.h> #import <CoreImage/CoreImage.h> #import <ImageIO/ImageIO.h> @interface ViewController : GLKViewController <AVCaptureVideoDataOutputSampleBufferDelegate>{ AVCaptureSession *avCaptureSession; CIContext *coreImageContext; CIImage *maskImage; CGSize screenSize; CGContextRef cgContext; GLuint _renderBuffer; float scale; } @property (strong, nonatomic) EAGLContext *context; -(void)setupCGContext; @end // ViewController.m #import "ViewController.h" @implementation ViewController @synthesize context; - (void)viewDidLoad { [super viewDidLoad]; self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; if (!self.context) { NSLog(@"Failed to create ES context"); } GLKView *view = (GLKView *)self.view; view.context = self.context; view.drawableDepthFormat = GLKViewDrawableDepthFormat24; coreImageContext = [CIContext contextWithEAGLContext:self.context]; glGenRenderbuffers(1, &_renderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffer); NSError *error; AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; AVCaptureVideoDataOutput *dataOutput = [[AVCaptureVideoDataOutput alloc] init]; [dataOutput setAlwaysDiscardsLateVideoFrames:YES]; [dataOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; [dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; avCaptureSession = [[AVCaptureSession alloc] init]; [avCaptureSession beginConfiguration]; [avCaptureSession setSessionPreset:AVCaptureSessionPreset1280x720]; [avCaptureSession addInput:input]; [avCaptureSession addOutput:dataOutput]; [avCaptureSession commitConfiguration]; [avCaptureSession startRunning]; [self setupCGContext]; CGImageRef cgImg = CGBitmapContextCreateImage(cgContext); maskImage = [CIImage imageWithCGImage:cgImg]; CGImageRelease(cgImg); } -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer); CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer]; image = [CIFilter filterWithName:@"CISepiaTone" keysAndValues:kCIInputImageKey, image, @"inputIntensity", [NSNumber numberWithFloat:0.8], nil].outputImage; [coreImageContext drawImage:image atPoint:CGPointZero fromRect:[image extent] ]; [self.context presentRenderbuffer:GL_RENDERBUFFER]; } -(void)setupCGContext { CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); NSUInteger bytesPerPixel = 4; NSUInteger bytesPerRow = bytesPerPixel * screenSize.width; NSUInteger bitsPerComponent = 8; cgContext = CGBitmapContextCreate(NULL, screenSize.width, screenSize.height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); } 

棕褐色filter的作品,但video慢一点。 当我不使用filter,video是正常的。 任何想法,我怎样才能改善video,使其更快?

谢谢。

正如我在这里所描述的,Core Image中的棕褐色filter不能实时运行,但其他filter可能会运行。 这取决于目标设备的硬件function以及iOS版本(Core Image在过去的几个iOS版本中的性能已得到显着改善)。

但是,如果我可能再次插入我的开源框架, GPUImage可以让你更快地做到这一点。 它可以在iPhone 4上以2.5毫秒的速度在640×480的video帧上应用棕褐色调滤镜,这对于来自该相机的30 FPSvideo而言足够快。

以下代码将在iOS设备上对后置摄像头的video进行实时过滤,并在面向肖像的视图中显示该video:

 videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack]; sepiaFilter = [[GPUImageSepiaFilter alloc] init]; GPUImageRotationFilter *rotationFilter = [[GPUImageRotationFilter alloc] initWithRotation:kGPUImageRotateRight]; [videoCamera addTarget:rotationFilter]; [rotationFilter addTarget:sepiaFilter]; filterView = [[GPUImageView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:filterView]; [sepiaFilter addTarget:filterView]; [videoCamera startCameraCapture]; 

我意识到这是一个古老的问题,但…

 [dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; 

该行正在使您的videocallback在主(UI)线程上被调用。

如果您将其更改为如下所示:

 [dataOutput setSampleBufferDelegate:self queue:dispatch_queue_create("cQ", DISPATCH_QUEUE_SERIAL)]; 

然后在你的callback中,如果你需要更新你的UI,你应该这样做:

 dispatch_async(dispatch_get_main_queue(), ^{ [coreImageContext drawImage:image atPoint:CGPointZero fromRect:[image extent] ]; [self.context presentRenderbuffer:GL_RENDERBUFFER]; }); 

这将有很大的帮助,因为在后台线程上执行计算量大的东西,并且图像绘制不会影响捕获。

边注:

盲目使用你在互联网上find的示例代码,却没有阅读技术的工作方式并不是开发应用程序的好方法(很多人都对此感到愧疚)

下列:

 CIFilter filterWithName:@"CISepiaTone" 

每次你得到一个缓冲区/框架都会被调用。 您只需要创build一次性筛选器。 所以把它移到外面,你仍然可以使用filter。