developer
2023-05-20 e12c7b4c22df631ebdcd16b2f98fbef8f738f92f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#import "GPUImageBuffer.h"
 
@interface GPUImageBuffer()
 
@end
 
@implementation GPUImageBuffer
 
@synthesize bufferSize = _bufferSize;
 
#pragma mark -
#pragma mark Initialization and teardown
 
- (id)init;
{
    if (!(self = [self initWithFragmentShaderFromString:kGPUImagePassthroughFragmentShaderString]))
    {
        return nil;
    }
    
    bufferedFramebuffers = [[NSMutableArray alloc] init];
//    [bufferedTextures addObject:[NSNumber numberWithInt:outputTexture]];
    _bufferSize = 1;
    
    return self;
}
 
- (void)dealloc
{
    for (GPUImageFramebuffer *currentFramebuffer in bufferedFramebuffers)
    {
        [currentFramebuffer unlock];
    }
}
 
#pragma mark -
#pragma mark GPUImageInput
 
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
{
    if ([bufferedFramebuffers count] >= _bufferSize)
    {
        outputFramebuffer = [bufferedFramebuffers objectAtIndex:0];
        [bufferedFramebuffers removeObjectAtIndex:0];
    }
    else
    {
        // Nothing yet in the buffer, so don't process further until the buffer is full
        outputFramebuffer = firstInputFramebuffer;
        [firstInputFramebuffer lock];
    }
    
    [bufferedFramebuffers addObject:firstInputFramebuffer];
 
    // Need to pass along rotation information, as we're just holding on to buffered framebuffers and not rotating them ourselves
    for (id<GPUImageInput> currentTarget in targets)
    {
        if (currentTarget != self.targetToIgnoreForUpdates)
        {
            NSInteger indexOfObject = [targets indexOfObject:currentTarget];
            NSInteger textureIndex = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];
            
            [currentTarget setInputRotation:inputRotation atIndex:textureIndex];
        }
    }
 
    // Let the downstream video elements see the previous frame from the buffer before rendering a new one into place
    [self informTargetsAboutNewFrameAtTime:frameTime];
 
//    [self renderToTextureWithVertices:imageVertices textureCoordinates:[[self class] textureCoordinatesForRotation:inputRotation]];
}
 
- (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates;
{
    // No need to render to another texture anymore, since we'll be hanging on to the textures in our buffer
}
 
#pragma mark -
#pragma mark Accessors
 
- (void)setBufferSize:(NSUInteger)newValue;
{
    if ( (newValue == _bufferSize) || (newValue < 1) )
    {
        return;
    }
        
    if (newValue > _bufferSize)
    {
        NSUInteger texturesToAdd = newValue - _bufferSize;
        for (NSUInteger currentTextureIndex = 0; currentTextureIndex < texturesToAdd; currentTextureIndex++)
        {
            // TODO: Deal with the growth of the size of the buffer by rotating framebuffers, no textures
        }
    }
    else
    {
        NSUInteger texturesToRemove = _bufferSize - newValue;
        for (NSUInteger currentTextureIndex = 0; currentTextureIndex < texturesToRemove; currentTextureIndex++)
        {
            GPUImageFramebuffer *lastFramebuffer = [bufferedFramebuffers lastObject];
            [bufferedFramebuffers removeObjectAtIndex:([bufferedFramebuffers count] - 1)];
            
            [lastFramebuffer unlock];
            lastFramebuffer = nil;
        }
    }
 
  _bufferSize = newValue;
}
 
@end