Sto provando a filtrare i video in iPhone. Ecco la struttura del programma e il codice sorgente:Il filtraggio dei video in iPhone è lento
AppDelegate.h
AppDelegate.m
ViewController.h
ViewController.m
Il file AppDelegate è lo stesso di default. Ecco il mio 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);
}
Il filtro seppia funziona, ma il video è un po 'più lento. Quando non applico il filtro, il video è normale. Qualche idea su come posso migliorare il video e renderlo più veloce?
Grazie.
Forse c'è del lavoro computazionale che è possibile scaricare in un thread separato. Si può leggere su 'NSThread',' NSOperation' e blocchi. –
non fa alcuna differenza, poiché sto filtrando e mostrando il video sullo schermo, delegando l'attività di filtraggio a un altro thread e ottenendo l'output filtrato da quel thread, e mostrandolo sullo schermo, non sarebbe lo stesso che fare il tutto nella stessa discussione?Usare un thread in background sarebbe utile se non fosse in tempo reale, immagino. Si prega di suggerire. Grazie. – rookieRailer
Il thread potrebbe probabilmente aiutare su dispositivi dual core. Esegui calcoli su un thread in background e aggiornamenti dell'interfaccia utente sul thread principale. Profilo con una versione più piccola della tua app, forse. –