Video editor fixes

This commit is contained in:
Ilya Laktyushin 2020-05-26 13:24:23 +03:00
parent eac07a216b
commit f103baf387
11 changed files with 150 additions and 189 deletions

View File

@ -9,7 +9,6 @@
#import "GPUImagePicture.h"
#import "GPUImageRawDataInput.h"
#import "GPUImageRawDataOutput.h"
#import "GPUImageTextureOutput.h"
#import "GPUImageFilterGroup.h"
#import "GPUImageFramebuffer.h"
#import "GPUImageFramebufferCache.h"

View File

@ -31,8 +31,10 @@ typedef struct GPUTextureOptions {
- (id)initWithSize:(CGSize)framebufferSize;
- (id)initWithSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)fboTextureOptions onlyTexture:(BOOL)onlyGenerateTexture;
- (id)initWithSize:(CGSize)framebufferSize overriddenTexture:(GLuint)inputTexture;
- (id)initWithSize:(CGSize)framebufferSize overridenFramebuffer:(GLuint)overridenFramebuffer overriddenTexture:(GLuint)inputTexture;
// Usage
- (void)useFramebuffer;
- (void)activateFramebuffer;
// Reference counting

View File

@ -92,6 +92,33 @@ static BOOL mark = false;
return self;
}
- (id)initWithSize:(CGSize)framebufferSize overridenFramebuffer:(GLuint)overridenFramebuffer overriddenTexture:(GLuint)inputTexture
{
if (!(self = [super init]))
{
return nil;
}
_mark = mark;
GPUTextureOptions defaultTextureOptions;
defaultTextureOptions.minFilter = GL_LINEAR;
defaultTextureOptions.magFilter = GL_LINEAR;
defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;
defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;
defaultTextureOptions.internalFormat = GL_RGBA;
defaultTextureOptions.format = GL_BGRA;
defaultTextureOptions.type = GL_UNSIGNED_BYTE;
_textureOptions = defaultTextureOptions;
_size = framebufferSize;
framebufferReferenceCount = 0;
referenceCountingDisabled = YES;
framebuffer = overridenFramebuffer;
_texture = inputTexture;
return self;
}
- (id)initWithSize:(CGSize)framebufferSize
{
_mark = mark;
@ -243,6 +270,11 @@ static BOOL mark = false;
#pragma mark -
#pragma mark Usage
- (void)useFramebuffer
{
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
}
- (void)activateFramebuffer
{
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
@ -263,6 +295,8 @@ static BOOL mark = false;
[fixer invalidate];
fixer = nil;
NSLog(@"Lock, %@, count = %d", self, framebufferReferenceCount);
}
- (void)unlock
@ -275,13 +309,15 @@ static BOOL mark = false;
NSAssert(framebufferReferenceCount > 0, @"Tried to overrelease a framebuffer, did you forget to call -useNextFrameForImageCapture before using -imageFromCurrentFramebuffer?");
framebufferReferenceCount--;
NSLog(@"Unlock, %@, count = %d", self, framebufferReferenceCount);
if (framebufferReferenceCount < 1)
{
[[GPUImageContext sharedFramebufferCache] returnFramebufferToCache:self];
[fixer invalidate];
fixer = nil;
} else if (framebufferReferenceCount == 1 && self.mark) {
fixer = [TGTimerTarget scheduledMainThreadTimerWithTarget:self action:@selector(fixTick) interval:0.35 repeat:false];
// fixer = [TGTimerTarget scheduledMainThreadTimerWithTarget:self action:@selector(fixTick) interval:0.35 repeat:false];
}
}

View File

@ -9,6 +9,8 @@
- (instancetype)initWithTexture:(GLuint)newInputTexture size:(CGSize)newTextureSize;
- (instancetype)initWithCIImage:(CIImage *)ciImage;
- (void)setCIImage:(CIImage *)ciImage;
- (void)processTextureWithFrameTime:(CMTime)frameTime synchronous:(bool)synchronous;
- (CGSize)textureSize;

View File

@ -1,7 +1,9 @@
#import "GPUImageTextureInput.h"
@implementation GPUImageTextureInput
{
CIContext *ciContext;
}
#pragma mark -
#pragma mark Initialization and teardown
@ -12,13 +14,10 @@
return nil;
}
textureSize = newTextureSize;
runSynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext useImageProcessingContext];
});
textureSize = newTextureSize;
runSynchronouslyOnVideoProcessingQueue(^{
outputFramebuffer = [[GPUImageFramebuffer alloc] initWithSize:newTextureSize overriddenTexture:newInputTexture];
});
@ -27,45 +26,92 @@
- (instancetype)initWithCIImage:(CIImage *)ciImage
{
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 = [ciImage imageByApplyingTransform:CGAffineTransformConcat(CGAffineTransformMakeScale(1.0f, -1.0f), CGAffineTransformMakeTranslation(0.0f, ciImage.extent.size.height))];
CIContext *ciContext = [CIContext contextWithEAGLContext:context options:@{kCIContextWorkingColorSpace: [NSNull null]}];
[ciContext drawImage:ciImage inRect:ciImage.extent fromRect:ciImage.extent];
if (self = [self initWithTexture:outputTexture size:ciImage.extent.size]) {
textureSize = ciImage.extent.size;
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
{
void (^block)(void) = ^

View File

@ -1,24 +0,0 @@
#import <Foundation/Foundation.h>
#import <CoreImage/CoreImage.h>
#import "GPUImageContext.h"
@protocol GPUImageTextureOutputDelegate;
@interface GPUImageTextureOutput : NSObject <GPUImageInput>
{
GPUImageFramebuffer *firstInputFramebuffer;
}
@property(readwrite, unsafe_unretained, nonatomic) id<GPUImageTextureOutputDelegate> delegate;
@property(readonly) GLuint texture;
@property(nonatomic) BOOL enabled;
- (CIImage *)CIImageWithSize:(CGSize)size;
- (void)doneWithTexture;
@end
@protocol GPUImageTextureOutputDelegate
- (void)newFrameReadyFromTextureOutput:(GPUImageTextureOutput *)callbackTextureOutput;
@end

View File

@ -1,94 +0,0 @@
#import "GPUImageTextureOutput.h"
@implementation GPUImageTextureOutput
@synthesize delegate = _delegate;
@synthesize texture = _texture;
@synthesize enabled;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super init]))
{
return nil;
}
self.enabled = YES;
return self;
}
- (void)doneWithTexture;
{
[firstInputFramebuffer unlock];
}
#pragma mark -
#pragma mark GPUImageInput protocol
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
{
[_delegate newFrameReadyFromTextureOutput:self];
}
- (NSInteger)nextAvailableTextureIndex;
{
return 0;
}
- (CIImage *)CIImageWithSize:(CGSize)size
{
EAGLContext *context = [[GPUImageContext sharedImageProcessingContext] context];
[EAGLContext setCurrentContext:context];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CIImage *image = [[CIImage alloc] initWithTexture:self.texture size:size flipped:true colorSpace:colorSpace];
CGColorSpaceRelease(colorSpace);
return image;
}
// TODO: Deal with the fact that the texture changes regularly as a result of the caching
- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;
{
firstInputFramebuffer = newInputFramebuffer;
[firstInputFramebuffer lock];
_texture = [firstInputFramebuffer texture];
}
- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;
{
}
- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;
{
}
- (CGSize)maximumOutputSize;
{
return CGSizeZero;
}
- (void)endProcessing
{
}
- (BOOL)shouldIgnoreUpdatesToThisTarget;
{
return NO;
}
- (BOOL)wantsMonochromeInput;
{
return NO;
}
- (void)setCurrentlyReceivingMonochromeInput:(BOOL)newValue;
{
}
@end

View File

@ -11,7 +11,6 @@
#import "PGPhotoEditorPicture.h"
#import "GPUImageTextureInput.h"
#import "GPUImageTextureOutput.h"
#import <LegacyComponents/PGPhotoEditorValues.h>
#import <LegacyComponents/TGVideoEditAdjustments.h>
@ -46,9 +45,7 @@
GPUImageOutput *_currentInput;
NSArray *_currentProcessChain;
GPUImageOutput <GPUImageInput> *_finalFilter;
GPUImageTextureOutput *_textureOutput;
PGPhotoHistogram *_currentHistogram;
PGPhotoHistogramGenerator *_histogramGenerator;
@ -94,17 +91,19 @@
_histogramPipe = [[SPipe alloc] init];
__weak PGPhotoEditor *weakSelf = self;
_histogramGenerator = [[PGPhotoHistogramGenerator alloc] init];
_histogramGenerator.histogramReady = ^(PGPhotoHistogram *histogram)
{
__strong PGPhotoEditor *strongSelf = weakSelf;
if (strongSelf == nil)
return;
if (!forVideo) {
__weak PGPhotoEditor *weakSelf = self;
_histogramGenerator = [[PGPhotoHistogramGenerator alloc] init];
_histogramGenerator.histogramReady = ^(PGPhotoHistogram *histogram)
{
__strong PGPhotoEditor *strongSelf = weakSelf;
if (strongSelf == nil)
return;
strongSelf->_currentHistogram = histogram;
strongSelf->_histogramPipe.sink(histogram);
};
strongSelf->_currentHistogram = histogram;
strongSelf->_histogramPipe.sink(histogram);
};
}
[self importAdjustments:adjustments];
}
@ -176,11 +175,12 @@
_currentProcessChain = nil;
[_currentInput removeAllTargets];
GPUImageTextureInput *input = [[GPUImageTextureInput alloc] initWithCIImage:ciImage];
_currentInput = input;
if (_textureOutput == nil) {
_textureOutput = [[GPUImageTextureOutput alloc] init];
if ([_currentInput isKindOfClass:[GPUImageTextureInput class]]) {
[(GPUImageTextureInput *)_currentInput setCIImage:ciImage];
} else {
GPUImageTextureInput *input = [[GPUImageTextureInput alloc] initWithCIImage:ciImage];
_currentInput = input;
}
_fullSize = true;
@ -355,15 +355,11 @@
}
_finalFilter = lastFilter;
if (_textureOutput != nil) {
[_finalFilter addTarget:_textureOutput];
}
if (previewOutput != nil) {
[_finalFilter addTarget:previewOutput.imageView];
}
if (!self.forVideo) {
if (_histogramGenerator != nil && !self.standalone) {
[_finalFilter addTarget:_histogramGenerator];
}
}
@ -394,13 +390,9 @@
- (CIImage *)currentResultCIImage {
__block CIImage *image = nil;
GPUImageOutput *currentInput = _currentInput;
[self processAnimated:false capture:true synchronous:true completion:^
{
image = [_finalFilter newCIImageFromCurrentlyProcessedOutput];
// if ([currentInput isKindOfClass:[GPUImageTextureInput class]]) {
// image = [_textureOutput CIImageWithSize:[(GPUImageTextureInput *)currentInput textureSize]];
// }
}];
return image;
}

View File

@ -221,7 +221,7 @@
SAtomic *context = [[SAtomic alloc] initWithValue:[TGMediaVideoConversionContext contextWithQueue:queue subscriber:subscriber]];
NSURL *outputUrl = [self _randomTemporaryURL];
NSString *path = TGComponentsPathForResource(@"blank_1080p", @"mp4");
NSString *path = TGComponentsPathForResource(@"blank", @"mp4");
AVAsset *avAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:path] options:nil];
NSArray *requiredKeys = @[ @"tracks", @"duration", @"playable" ];
@ -388,8 +388,10 @@
CGSize size = resultImage.extent.size;
if (editor != nil) {
NSLog(@"setCIImage");
[editor setCIImage:resultImage];
resultImage = editor.currentResultCIImage;
NSLog(@"resultCIImage");
}
if (overlayImage != nil && overlayImage.size.width > 0.0) {