我无法弄清楚当我开始使用GPUImageMovieWriter录制时会发生什么。虽然它只是预览一切正常,但是当我按下录制按钮时,我的过滤器会崩溃。我无法找到GPUImageMovieWriter如何更改我的过滤器,帮助我。
我的开始记录操作:
- (void)cameraButton:(id)sender
{
// Recording.
NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]);
NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
self.movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(1080.0, 1920.0)];
self.movieWriter.encodingLiveVideo = YES;
self.movieWriter.shouldPassthroughAudio = YES;
[self.blendFilter addTarget:self.movieWriter];
self.videoCamera.audioEncodingTarget = self.movieWriter;
// Start recording.
[self.movieWriter startRecording];
double delayInSeconds = 10.0;
dispatch_time_t stopTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(stopTime, dispatch_get_main_queue(), ^(void){
[self.blendFilter removeTarget:self.movieWriter];
self.videoCamera.audioEncodingTarget = nil;
[self.movieWriter finishRecording];
UISaveVideoAtPathToSavedPhotosAlbum(pathToMovie, nil, NULL, NULL);
NSLog(@"Movie completed");
});
}
我的滤镜按形状裁剪输入图像,均匀采样2D形状。
我的过滤器代码:
#import "GPUImageShapeCropFilter.h"
NSString *const kGPUImageShapeCropShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp float aspectRatio;
uniform highp vec2 center;
uniform highp float radius;
uniform highp float scale;
uniform sampler2D shape;
void main()
{
highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
lowp vec4 shapeColor = texture2D(shape, textureCoordinateToUse);
textureCoordinateToUse = textureCoordinate;
textureCoordinateToUse -= center;
textureCoordinateToUse = textureCoordinateToUse * scale;
textureCoordinateToUse += center;
if (shapeColor.w > 0.0) {
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinateToUse);
textureColor.w = shapeColor.w;
gl_FragColor = textureColor;
} else {
gl_FragColor = shapeColor;
}
}
);
@interface GPUImageShapeCropFilter ()
{
GLint _aspectRatioUniform;
GLint _radiusUniform;
GLint _centerUniform;
GLint _scaleUniform;
GLuint _oldTextureIndex;
}
- (void)adjustAspectRatio;
@property (readwrite, nonatomic) CGFloat aspectRatio;
@end
@implementation GPUImageShapeCropFilter
@synthesize aspectRatio = _aspectRatio;
@synthesize center = _center;
@synthesize radius = _radius;
@synthesize scale = _scale;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init
{
self = [super initWithFragmentShaderFromString:kGPUImageShapeCropShaderString];
if (!self) {
return nil;
}
// Get uniforms.
_aspectRatioUniform = [filterProgram uniformIndex: @"aspectRatio"];
_radiusUniform = [filterProgram uniformIndex: @"radius"];
_scaleUniform = [filterProgram uniformIndex: @"scale"];
_centerUniform = [filterProgram uniformIndex: @"center"];
// Set default values.
self.scale = 0.5;
self.center = CGPointMake(0.5, 0.5);
[self setShape:[UIImage imageNamed:@"circle"]];
return self;
}
- (void)setShape:(UIImage *)shape
{
[self setTexture:shape forUniform:@"shape"];
}
- (void)setTexture:(UIImage *)image forUniform:(NSString *)uniform
{
// Find texture size.
CGSize sizeOfImage = [image size];
CGFloat scaleOfImage = [image scale];
CGSize pixelSizeOfImage = CGSizeMake(scaleOfImage * sizeOfImage.width, scaleOfImage * sizeOfImage.height);
// Create context.
GLubyte * spriteData = (GLubyte *)malloc(pixelSizeOfImage.width * pixelSizeOfImage.height * 4 * sizeof(GLubyte));
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, pixelSizeOfImage.width, pixelSizeOfImage.height, 8, pixelSizeOfImage.width * 4, CGImageGetColorSpace(image.CGImage), (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
// Draw image into context.
CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, pixelSizeOfImage.width, pixelSizeOfImage.height), image.CGImage);
// Get uniform of texture
GLuint uniformIndex = [filterProgram uniformIndex:uniform];
// Generate texture.
GLuint textureIndex;
glGenTextures(1, &textureIndex);
glBindTexture(GL_TEXTURE_2D, textureIndex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Create texture.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixelSizeOfImage.width, pixelSizeOfImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureIndex);
// "Send" to shader.
glUniform1i(uniformIndex, 1);
// Remove old texture if it is.
if (_oldTextureIndex) {
glDeleteTextures(1, &_oldTextureIndex);
}
_oldTextureIndex = textureIndex;
free(spriteData);
CGContextRelease(spriteContext);
}
#pragma mark -
#pragma mark Accessors
- (void)adjustAspectRatio;
{
if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) {
[self setAspectRatio:inputTextureSize.width / inputTextureSize.height];
} else {
[self setAspectRatio:inputTextureSize.height / inputTextureSize.width];
}
}
- (void)forceProcessingAtSize:(CGSize)frameSize;
{
[super forceProcessingAtSize:frameSize];
[self adjustAspectRatio];
}
- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex
{
CGSize oldInputSize = inputTextureSize;
[super setInputSize:newSize atIndex:textureIndex];
if ( (!CGSizeEqualToSize(oldInputSize, inputTextureSize)) && (!CGSizeEqualToSize(newSize, CGSizeZero)) ) {
[self adjustAspectRatio];
}
}
- (void)setAspectRatio:(CGFloat)newValue
{
_aspectRatio = newValue;
[self setFloat:self.aspectRatio forUniform:_aspectRatioUniform program:filterProgram];
}
- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;
{
[super setInputRotation:newInputRotation atIndex:textureIndex];
[self setCenter:self.center];
[self adjustAspectRatio];
}
- (void)setScale: (CGFloat)newValue;
{
_scale = newValue;
[self setFloat:self.scale forUniform:_scaleUniform program:filterProgram];
}
- (void)setCenter: (CGPoint)newValue;
{
_center = newValue;
CGPoint rotatedPoint = [self rotatedPoint:self.center forRotation:inputRotation];
[self setPoint:rotatedPoint forUniform:_centerUniform program:filterProgram];
}
@end