Skip to content

Commit

Permalink
SGVideoRenderer: DrawingLoop.
Browse files Browse the repository at this point in the history
  • Loading branch information
libobjc committed Jun 28, 2019
1 parent 6b48b21 commit c8629e2
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 25 deletions.
16 changes: 16 additions & 0 deletions SGPlayer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
9C11816A22C4E23200A12FD4 /* SGMetalViewport.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C11816422C4E23200A12FD4 /* SGMetalViewport.m */; };
9C13638E213934030025C72B /* SGGLBGRAProgram.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C13638C213934030025C72B /* SGGLBGRAProgram.h */; };
9C13638F213934030025C72B /* SGGLBGRAProgram.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C13638D213934030025C72B /* SGGLBGRAProgram.m */; };
9C17554922C5B5B3003A93BC /* SGRenderTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C17554722C5B5B3003A93BC /* SGRenderTimer.h */; };
9C17554A22C5B5B3003A93BC /* SGRenderTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C17554722C5B5B3003A93BC /* SGRenderTimer.h */; };
9C17554B22C5B5B3003A93BC /* SGRenderTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C17554722C5B5B3003A93BC /* SGRenderTimer.h */; };
9C17554C22C5B5B3003A93BC /* SGRenderTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C17554822C5B5B3003A93BC /* SGRenderTimer.m */; };
9C17554D22C5B5B3003A93BC /* SGRenderTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C17554822C5B5B3003A93BC /* SGRenderTimer.m */; };
9C17554E22C5B5B3003A93BC /* SGRenderTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C17554822C5B5B3003A93BC /* SGRenderTimer.m */; };
9C1944E120198CEC00184416 /* SGGLPlaneModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1944DF20198CEC00184416 /* SGGLPlaneModel.h */; };
9C1944E420198CEC00184416 /* SGGLPlaneModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C1944E020198CEC00184416 /* SGGLPlaneModel.m */; };
9C1944E92019A9AA00184416 /* SGGLSphereModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1944E72019A9AA00184416 /* SGGLSphereModel.h */; };
Expand Down Expand Up @@ -699,6 +705,8 @@
9C11816422C4E23200A12FD4 /* SGMetalViewport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SGMetalViewport.m; sourceTree = "<group>"; };
9C13638C213934030025C72B /* SGGLBGRAProgram.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SGGLBGRAProgram.h; sourceTree = "<group>"; };
9C13638D213934030025C72B /* SGGLBGRAProgram.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SGGLBGRAProgram.m; sourceTree = "<group>"; };
9C17554722C5B5B3003A93BC /* SGRenderTimer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SGRenderTimer.h; sourceTree = "<group>"; };
9C17554822C5B5B3003A93BC /* SGRenderTimer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SGRenderTimer.m; sourceTree = "<group>"; };
9C1944DF20198CEC00184416 /* SGGLPlaneModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SGGLPlaneModel.h; sourceTree = "<group>"; };
9C1944E020198CEC00184416 /* SGGLPlaneModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SGGLPlaneModel.m; sourceTree = "<group>"; };
9C1944E72019A9AA00184416 /* SGGLSphereModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SGGLSphereModel.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1569,6 +1577,8 @@
9CF15E062011AE0700585326 /* SGAudioRenderer.m */,
9C2C55A12015C1E100131E15 /* SGVideoRenderer.h */,
9C2C55A22015C1E100131E15 /* SGVideoRenderer.m */,
9C17554722C5B5B3003A93BC /* SGRenderTimer.h */,
9C17554822C5B5B3003A93BC /* SGRenderTimer.m */,
);
path = SGRenderer;
sourceTree = "<group>";
Expand Down Expand Up @@ -1670,6 +1680,7 @@
9C86386721904A0900D730EC /* SGFFmpeg.h in Headers */,
9C86386821904A0900D730EC /* SGPLFTargets.h in Headers */,
9C86386921904A0900D730EC /* SGRenderer+Internal.h in Headers */,
9C17554A22C5B5B3003A93BC /* SGRenderTimer.h in Headers */,
9CA57933219DAA270061093B /* SGCodecDescription.h in Headers */,
9C86386B21904A0900D730EC /* SGPLFObject.h in Headers */,
9C8D6B8B22C4A19500985D55 /* SGMetalRenderPipeline.h in Headers */,
Expand Down Expand Up @@ -1796,6 +1807,7 @@
9CD79F162190068E00E39A7D /* SGGLNV12Program.h in Headers */,
9C8D6B8C22C4A19500985D55 /* SGMetalRenderPipeline.h in Headers */,
9CD79F1B2190068E00E39A7D /* SGFFmpeg.h in Headers */,
9C17554B22C5B5B3003A93BC /* SGRenderTimer.h in Headers */,
9CD79F232190068E00E39A7D /* SGPLFTargets.h in Headers */,
9CD79F242190068E00E39A7D /* SGRenderer+Internal.h in Headers */,
9CD79F272190068E00E39A7D /* SGPLFObject.h in Headers */,
Expand Down Expand Up @@ -1978,6 +1990,7 @@
9C13638E213934030025C72B /* SGGLBGRAProgram.h in Headers */,
9CE68430200DD12F007BD834 /* SGAudioStreamPlayer.h in Headers */,
9C8D6B7522C4A19500985D55 /* SGMetalSphereModel.h in Headers */,
9C17554922C5B5B3003A93BC /* SGRenderTimer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -2194,6 +2207,7 @@
9C86382E21904A0900D730EC /* SGAudioFrame.m in Sources */,
9C8D6B5222C4A19500985D55 /* SGMetalRenderPipelinePool.m in Sources */,
9C86382F21904A0900D730EC /* SGGLViewport.m in Sources */,
9C17554D22C5B5B3003A93BC /* SGRenderTimer.m in Sources */,
9CC2AD8222A660080095A081 /* SGPaddingSegment.m in Sources */,
9C86383021904A0900D730EC /* SGAsset.m in Sources */,
9C86383121904A0900D730EC /* SGOptions.m in Sources */,
Expand Down Expand Up @@ -2294,6 +2308,7 @@
9CD79ED52190068E00E39A7D /* SGAudioFrame.m in Sources */,
9C8D6B5322C4A19500985D55 /* SGMetalRenderPipelinePool.m in Sources */,
9CD79ED62190068E00E39A7D /* SGGLViewport.m in Sources */,
9C17554E22C5B5B3003A93BC /* SGRenderTimer.m in Sources */,
9CC2AD8322A660080095A081 /* SGPaddingSegment.m in Sources */,
9CD79ED72190068E00E39A7D /* SGAsset.m in Sources */,
9CD79ED82190068E00E39A7D /* SGOptions.m in Sources */,
Expand Down Expand Up @@ -2401,6 +2416,7 @@
9CF63FC3211D8E33001B2684 /* SGAsset.m in Sources */,
9C43D50E2187037200235169 /* SGOptions.m in Sources */,
9C4663CD20D0F83600CADDA7 /* SGTime.m in Sources */,
9C17554C22C5B5B3003A93BC /* SGRenderTimer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
21 changes: 21 additions & 0 deletions SGPlayer/Classes/Core/SGRenderer/SGRenderTimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// SGRenderTimer.h
// SGPlayer
//
// Created by Single on 2019/6/28.
// Copyright © 2019 single. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface SGRenderTimer : NSObject

- (instancetype)initWithHandler:(dispatch_block_t)handler;

@property (nonatomic) NSTimeInterval timeInterval;
@property (nonatomic) BOOL paused;

- (void)start;
- (void)stop;

@end
83 changes: 83 additions & 0 deletions SGPlayer/Classes/Core/SGRenderer/SGRenderTimer.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// SGRenderTimer.m
// SGPlayer
//
// Created by Single on 2019/6/28.
// Copyright © 2019 single. All rights reserved.
//

#import "SGRenderTimer.h"

@interface SGRenderTimer ()

@property (nonatomic, copy) dispatch_block_t handler;
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation SGRenderTimer

- (instancetype)initWithHandler:(dispatch_block_t)handler
{
if (self = [super init]) {
self.handler = handler;
}
return self;
}

- (void)dealloc
{
[self stop];
}

- (void)timerHandler
{
if (self.handler) {
self.handler();
}
}

- (void)setTimeInterval:(NSTimeInterval)timeInterval
{
if (self->_timeInterval != timeInterval) {
self->_timeInterval = timeInterval;
[self start];
}
}

- (void)setPaused:(BOOL)paused
{
if (self->_paused != paused) {
self->_paused = paused;
[self fire];
}
}

- (void)start
{
[self stop];
self->_timer = [NSTimer timerWithTimeInterval:self->_timeInterval
target:self
selector:@selector(timerHandler)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self->_timer
forMode:NSRunLoopCommonModes];
[self fire];
}

- (void)stop
{
[self->_timer invalidate];
self->_timer = nil;
}

- (void)fire
{
self->_timer.fireDate =
self->_paused ?
[NSDate distantFuture] :
[NSDate distantPast];
}

@end
53 changes: 28 additions & 25 deletions SGPlayer/Classes/Core/SGRenderer/SGVideoRenderer.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
#import "SGVideoRenderer.h"
#import "SGRenderer+Internal.h"
#import "SGVRMatrixMaker.h"
#import "SGRenderTimer.h"
#import "SGOptions.h"
#import "SGMapping.h"
#import "SGOpenGL.h"
#import "SGMetal.h"
#import "SGMacro.h"
#import "SGLock.h"
Expand All @@ -31,7 +31,7 @@ @interface SGVideoRenderer () <MTKViewDelegate>

@property (nonatomic, strong, readonly) NSLock *lock;
@property (nonatomic, strong, readonly) SGClock *clock;
@property (nonatomic, strong, readonly) SGGLTimer *fetchTimer;
@property (nonatomic, strong, readonly) SGRenderTimer *fetchTimer;
@property (nonatomic, strong, readonly) SGVideoFrame *currentFrame;
@property (nonatomic, strong, readonly) SGVRMatrixMaker *matrixMaker;

Expand Down Expand Up @@ -77,11 +77,9 @@ - (instancetype)initWithClock:(SGClock *)clock

- (void)dealloc
{
[self performSelectorOnMainThread:@selector(destoryMetal)
[self performSelectorOnMainThread:@selector(destoryDrawingLoop)
withObject:nil
waitUntilDone:YES];
[self->_fetchTimer invalidate];
self->_fetchTimer = nil;
[self->_currentFrame unlock];
self->_currentFrame = nil;
}
Expand Down Expand Up @@ -167,16 +165,9 @@ - (BOOL)open
return [self setState:SGRenderableStatePaused];
}, ^BOOL(SGBlock block) {
block();
[self performSelectorOnMainThread:@selector(setupMetal)
[self performSelectorOnMainThread:@selector(setupDrawingLoop)
withObject:nil
waitUntilDone:YES];
SGWeakify(self)
NSTimeInterval interval = 0.5 / self->_preferredFramesPerSecond;
self->_fetchTimer = [[SGGLTimer alloc] initWithTimeInterval:interval handler:^{
SGStrongify(self)
[self fetchTimerHandler];
}];
self->_fetchTimer.paused = NO;
return YES;
});
}
Expand All @@ -187,17 +178,15 @@ - (BOOL)close
SGBlock b1 = [self setState:SGRenderableStateNone];
[self->_currentFrame unlock];
self->_currentFrame = nil;
self->_flags.hasNewFrame = NO;
self->_flags.framesFetched = 0;
self->_flags.framesDisplayed = 0;
self->_flags.hasNewFrame = NO;
self->_capacity = SGCapacityCreate();
return ^{b1();};
}, ^BOOL(SGBlock block) {
[self performSelectorOnMainThread:@selector(destoryMetal)
[self performSelectorOnMainThread:@selector(destoryDrawingLoop)
withObject:nil
waitUntilDone:YES];
[self->_fetchTimer invalidate];
self->_fetchTimer = nil;
block();
return YES;
});
Expand Down Expand Up @@ -243,9 +232,9 @@ - (BOOL)flush
}, ^SGBlock {
[self->_currentFrame unlock];
self->_currentFrame = nil;
self->_flags.hasNewFrame = NO;
self->_flags.framesFetched = 0;
self->_flags.framesDisplayed = 0;
self->_flags.hasNewFrame = NO;
return nil;
}, ^BOOL(SGBlock block) {
self->_metalView.paused = NO;
Expand Down Expand Up @@ -318,8 +307,8 @@ - (void)fetchTimerHandler
capacity.duration = duration;
[self->_currentFrame unlock];
self->_currentFrame = newFrame;
self->_flags.framesFetched += 1;
self->_flags.hasNewFrame = YES;
self->_flags.framesFetched += 1;
self->_flags.currentFrameEndTime = currentMediaTime + CMTimeGetSeconds(duration);
if (self->_frameOutput) {
[newFrame lock];
Expand Down Expand Up @@ -470,7 +459,7 @@ - (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size

#pragma mark - Metal

- (void)setupMetal
- (void)setupDrawingLoop
{
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
self->_renderer = [[SGMetalRenderer alloc] initWithDevice:device];
Expand All @@ -487,11 +476,19 @@ - (void)setupMetal
self->_metalView.translatesAutoresizingMaskIntoConstraints = NO;
self->_metalView.colorPixelFormat = MTLPixelFormatBGRA8Unorm;
self->_metalView.delegate = self;
[self layoutMetalViewIfNeeded];
SGWeakify(self)
self->_fetchTimer = [[SGRenderTimer alloc] initWithHandler:^{
SGStrongify(self)
[self fetchTimerHandler];
}];
[self updateMetalView];
[self updateTimeInterval];
}

- (void)destoryMetal
- (void)destoryDrawingLoop
{
[self->_fetchTimer stop];
self->_fetchTimer = nil;
[self->_metalView removeFromSuperview];
self->_metalView = nil;
self->_renderer = nil;
Expand All @@ -507,15 +504,15 @@ - (void)setView:(SGPLFView *)view
{
if (self->_view != view) {
self->_view = view;
[self layoutMetalViewIfNeeded];
[self updateMetalView];
}
}

- (void)setPreferredFramesPerSecond:(NSInteger)preferredFramesPerSecond
{
if (self->_preferredFramesPerSecond != preferredFramesPerSecond) {
self->_preferredFramesPerSecond = preferredFramesPerSecond;
self->_metalView.preferredFramesPerSecond = self->_preferredFramesPerSecond;
[self updateTimeInterval];
}
}

Expand All @@ -538,7 +535,7 @@ - (void)setDisplayMode:(SGDisplayMode)displayMode
}
}

- (void)layoutMetalViewIfNeeded
- (void)updateMetalView
{
if (self->_view &&
self->_metalView &&
Expand Down Expand Up @@ -578,4 +575,10 @@ - (void)layoutMetalViewIfNeeded
}
}

- (void)updateTimeInterval
{
self->_fetchTimer.timeInterval = 0.5 / self->_preferredFramesPerSecond;
self->_metalView.preferredFramesPerSecond = self->_preferredFramesPerSecond;
}

@end

0 comments on commit c8629e2

Please sign in to comment.