iPhone에서 비디오를 필터링하려고합니다. 다음은 프로그램 구조 및 소스 코드입니다.iPhone에서 비디오 필터링 속도가 느림
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);
}
세피아 필터가 작동하지만 비디오가 느린 조금이다. 필터를 적용하지 않으면 비디오가 정상입니다. 비디오를 개선하고 더 빨리 만들 수있는 방법에 대한 아이디어가 있습니까?
감사합니다.
아마도 별도의 스레드로 오프로드 할 수있는 계산 작업이있을 것입니다. 'NSThread','NSOperation' 및 블록을 읽을 수 있습니다. –
그것은 필터링을하고 화면에 비디오를 보여주고 필터링 작업을 다른 스레드에 위임 한 다음 해당 스레드에서 필터링 된 출력을 가져 와서 화면에 표시하면 차이가 있습니다. 같은 실에있는 모든 것?실시간 스레드가 아닌 경우 백그라운드 스레드를 사용하면 도움이 될 것입니다. 제발 제안 해주세요. 감사. – rookieRailer
스레딩은 듀얼 코어 장치에서 도움이 될 것입니다. 백그라운드 스레드에서의 계산과 메인 스레드에서의 UI 업데이트. 더 작은 버전의 앱으로 프로필하십시오. –