赞
踩
最近在研究OC的生物活检方面的实现,发现SDK中自带有相应的功能类,则进行了调研与实现。
实现过程中发现一个比较坑人的一个地方,就是GPUIMAGE这个框架里面对于视频采集使用的YUV格式,而YUV格式无法与OC的类库进行配合实现实时识别。
现在我们来剖析一下GPUImageVideoCamera的实现:
- @interface GPUImageVideoCamera : GPUImageOutput <AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate>
-
-
- - (id)initWithSessionPreset:(NSString *)sessionPreset cameraPosition:(AVCaptureDevicePosition)cameraPosition;
可以看到提供了一个初始化方法,此初始化方法内部的代码如下:
- - (id)initWithSessionPreset:(NSString *)sessionPreset cameraPosition:(AVCaptureDevicePosition)cameraPosition;
- {
- if (!(self = [super init]))
- {
- return nil;
- }
-
- cameraProcessingQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);
- audioProcessingQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0);
-
- frameRenderingSemaphore = dispatch_semaphore_create(1);
-
- _frameRate = 0; // This will not set frame rate unless this value gets set to 1 or above
- _runBenchmark = NO;
- capturePaused = NO;
- outputRotation = kGPUImageNoRotation;
- internalRotation = kGPUImageNoRotation;
- captureAsYUV = YES;
- _preferredConversion = kColorConversion709;
-
- // Grab the back-facing or front-facing camera
- _inputCamera = nil;
- NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
- for (AVCaptureDevice *device in devices)
- {
- if ([device position] == cameraPosition)
- {
- _inputCamera = device;
- }
- }
-
- if (!_inputCamera) {
- return nil;
- }
-
- // Create the capture session
- _captureSession = [[AVCaptureSession alloc] init];
-
- [_captureSession beginConfiguration];
-
- // Add the video input
- NSError *error = nil;
- videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:_inputCamera error:&error];
- if ([_captureSession canAddInput:videoInput])
- {
- [_captureSession addInput:videoInput];
- }
-
- // Add the video frame output
- videoOutput = [[AVCaptureVideoDataOutput alloc] init];
- [videoOutput setAlwaysDiscardsLateVideoFrames:NO];
-
- // if (captureAsYUV && [GPUImageContext deviceSupportsRedTextures])
- if (captureAsYUV && [GPUImageContext supportsFastTextureUpload])
- {
- BOOL supportsFullYUVRange = NO;
- NSArray *supportedPixelFormats = videoOutput.availableVideoCVPixelFormatTypes;
- for (NSNumber *currentPixelFormat in supportedPixelFormats)
- {
- if ([currentPixelFormat intValue] == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
- {
- supportsFullYUVRange = YES;
- }
- }
-
- if (supportsFullYUVRange)
- {
- [videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
- isFullYUVRange = YES;
- }
- else
- {
- [videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
- isFullYUVRange = NO;
- }
- }
- else
- {
- [videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
- }
-
- runSynchronouslyOnVideoProcessingQueue(^{
-
- if (captureAsYUV)
- {
- [GPUImageContext useImageProcessingContext];
- // if ([GPUImageContext deviceSupportsRedTextures])
- // {
- // yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVVideoRangeConversionForRGFragmentShaderString];
- // }
- // else
- // {
- if (isFullYUVRange)
- {
- yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVFullRangeConversionForLAFragmentShaderString];
- }
- else
- {
- yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVVideoRangeConversionForLAFragmentShaderString];
- }
-
- // }
-
- if (!yuvConversionProgram.initialized)
- {
- [yuvConversionProgram addAttribute:@"position"];
- [yuvConversionProgram addAttribute:@"inputTextureCoordinate"];
-
- if (![yuvConversionProgram link])
- {
- NSString *progLog = [yuvConversionProgram programLog];
- NSLog(@"Program link log: %@", progLog);
- NSString *fragLog = [yuvConversionProgram fragmentShaderLog];
- NSLog(@"Fragment shader compile log: %@", fragLog);
- NSString *vertLog = [yuvConversionProgram vertexShaderLog];
- NSLog(@"Vertex shader compile log: %@", vertLog);
- yuvConversionProgram = nil;
- NSAssert(NO, @"Filter shader link failed");
- }
- }
-
- yuvConversionPositionAttribute = [yuvConversionProgram attributeIndex:@"position"];
- yuvConversionTextureCoordinateAttribute = [yuvConversionProgram attributeIndex:@"inputTextureCoordinate"];
- yuvConversionLuminanceTextureUniform = [yuvConversionProgram uniformIndex:@"luminanceTexture"];
- yuvConversionChrominanceTextureUniform = [yuvConversionProgram uniformIndex:@"chrominanceTexture"];
- yuvConversionMatrixUniform = [yuvConversionProgram uniformIndex:@"colorConversionMatrix"];
-
- [GPUImageContext setActiveShaderProgram:yuvConversionProgram];
-
- glEnableVertexAttribArray(yuvConversionPositionAttribute);
- glEnableVertexAttribArray(yuvConversionTextureCoordinateAttribute);
- }
- });
-
- [videoOutput setSampleBufferDelegate:self queue:cameraProcessingQueue];
- if ([_captureSession

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。