#import "GPUImageTextureInput.h" @implementation GPUImageTextureInput { CIContext *ciContext; } #pragma mark - #pragma mark Initialization and teardown - (instancetype)initWithTexture:(GLuint)newInputTexture size:(CGSize)newTextureSize { if (!(self = [super init])) { return nil; } textureSize = newTextureSize; runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; outputFramebuffer = [[GPUImageFramebuffer alloc] initWithSize:newTextureSize overriddenTexture:newInputTexture]; }); return self; } - (instancetype)initWithCIImage:(CIImage *)ciImage { if (!(self = [super init])) { return nil; } textureSize = ciImage.extent.size; runSynchronouslyOnVideoProcessingQueue(^{ EAGLContext *context = [[GPUImageContext sharedImageProcessingContext] context]; [EAGLContext setCurrentContext:context]; GLsizei backingWidth = ciImage.extent.size.width; GLsizei backingHeight = ciImage.extent.size.height; GLuint outputTexture, defaultFramebuffer; glActiveTexture(GL_TEXTURE0); glGenTextures(1, &outputTexture); glBindTexture(GL_TEXTURE_2D, outputTexture); 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); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE1); glGenFramebuffers(1, &defaultFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); glBindTexture(GL_TEXTURE_2D, outputTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outputTexture, 0); NSAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, @"Incomplete filter FBO: %d", glCheckFramebufferStatus(GL_FRAMEBUFFER)); glBindTexture(GL_TEXTURE_2D, 0); CIImage *updatedCIImage = [ciImage imageByApplyingTransform:CGAffineTransformConcat(CGAffineTransformMakeScale(1.0f, -1.0f), CGAffineTransformMakeTranslation(0.0f, ciImage.extent.size.height))]; ciContext = [CIContext contextWithEAGLContext:context options:@{kCIContextWorkingColorSpace: [NSNull null]}]; [ciContext drawImage:updatedCIImage inRect:updatedCIImage.extent fromRect:updatedCIImage.extent]; [GPUImageContext useImageProcessingContext]; outputFramebuffer = [[GPUImageFramebuffer alloc] initWithSize:ciImage.extent.size overridenFramebuffer:defaultFramebuffer overriddenTexture:outputTexture]; }); return self; } - (void)dealloc { NSLog(@"deall texinp"); } - (void)setCIImage:(CIImage *)ciImage { runSynchronouslyOnVideoProcessingQueue(^{ EAGLContext *context = [[GPUImageContext sharedImageProcessingContext] context]; [EAGLContext setCurrentContext:context]; GLsizei backingWidth = ciImage.extent.size.width; GLsizei backingHeight = ciImage.extent.size.height; GLint outputTexture = outputFramebuffer.texture; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, outputTexture); 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); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE1); [outputFramebuffer useFramebuffer]; glBindTexture(GL_TEXTURE_2D, outputTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outputTexture, 0); NSAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, @"Incomplete filter FBO: %d", glCheckFramebufferStatus(GL_FRAMEBUFFER)); glBindTexture(GL_TEXTURE_2D, 0); CIImage *updatedCIImage = [ciImage imageByApplyingTransform:CGAffineTransformConcat(CGAffineTransformMakeScale(1.0f, -1.0f), CGAffineTransformMakeTranslation(0.0f, ciImage.extent.size.height))]; [ciContext drawImage:updatedCIImage inRect:updatedCIImage.extent fromRect:updatedCIImage.extent]; }); } - (void)processTextureWithFrameTime:(CMTime)frameTime synchronous:(bool)synchronous completion:(void (^)(void))completion { void (^block)(void) = ^ { for (id currentTarget in targets) { NSInteger indexOfObject = [targets indexOfObject:currentTarget]; NSInteger targetTextureIndex = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; [currentTarget setInputSize:textureSize atIndex:targetTextureIndex]; [currentTarget setInputFramebuffer:outputFramebuffer atIndex:targetTextureIndex]; [currentTarget newFrameReadyAtTime:frameTime atIndex:targetTextureIndex]; } if (completion != nil) completion(); }; if (synchronous) runSynchronouslyOnVideoProcessingQueue(block); else runAsynchronouslyOnVideoProcessingQueue(block); } - (CGSize)textureSize { return textureSize; } @end