Skip to content

Commit

Permalink
SGVideoDecoder: Record last frame.
Browse files Browse the repository at this point in the history
  • Loading branch information
libobjc committed Nov 2, 2019
1 parent b56807c commit 18e359b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 2 deletions.
8 changes: 8 additions & 0 deletions SGPlayer/Classes/Core/SGDecoder/SGAudioDecoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ @implementation SGAudioDecoder

@synthesize options = _options;

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

- (void)setup
{
self->_flags.nextTimeStamp = 0;
Expand Down Expand Up @@ -177,6 +182,9 @@ - (void)flush

- (NSArray<__kindof SGFrame *> *)clipFrames:(NSArray<__kindof SGFrame *> *)frames timeRange:(CMTimeRange)timeRange
{
if (frames.count <= 0) {
return nil;
}
if (!SGCMTimeIsValid(timeRange.start, NO)) {
return frames;
}
Expand Down
30 changes: 29 additions & 1 deletion SGPlayer/Classes/Core/SGDecoder/SGVideoDecoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ @interface SGVideoDecoder ()
{
struct {
BOOL needsAlignment;
NSUInteger outputCount;
} _flags;
}

@property (nonatomic, strong, readonly) SGVideoFrame *lastFrame;
@property (nonatomic, strong, readonly) SGDecodeContext *codecContext;
@property (nonatomic, strong, readonly) SGCodecDescriptor *codecDescriptor;

Expand All @@ -29,6 +31,11 @@ @implementation SGVideoDecoder

@synthesize options = _options;

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

- (void)setup
{
self->_flags.needsAlignment = YES;
Expand All @@ -42,17 +49,23 @@ - (void)setup

- (void)destroy
{
self->_flags.outputCount = 0;
self->_flags.needsAlignment = YES;
[self->_codecContext close];
self->_codecContext = nil;
[self->_lastFrame unlock];
self->_lastFrame = nil;
}

#pragma mark - Control

- (void)flush
{
self->_flags.outputCount = 0;
self->_flags.needsAlignment = YES;
[self->_codecContext flush];
[self->_lastFrame unlock];
self->_lastFrame = nil;
}

- (NSArray<__kindof SGFrame *> *)decode:(SGPacket *)packet
Expand Down Expand Up @@ -83,12 +96,21 @@ - (void)flush
}
break;
}
self->_flags.outputCount += ret.count;
return ret;
}

- (NSArray<__kindof SGFrame *> *)finish
{
return [self processPacket:nil];
NSArray<SGFrame *> *objs = [self processPacket:nil];
if (objs.count > 0) {
[self->_lastFrame unlock];
} else if (self->_lastFrame) {
objs = @[self->_lastFrame];
}
self->_lastFrame = nil;
self->_flags.outputCount += objs.count;
return objs;
}

#pragma mark - Process
Expand Down Expand Up @@ -118,9 +140,15 @@ - (void)flush

- (NSArray<__kindof SGFrame *> *)clipFrames:(NSArray<__kindof SGFrame *> *)frames timeRange:(CMTimeRange)timeRange
{
if (frames.count <= 0) {
return nil;
}
if (!SGCMTimeIsValid(timeRange.start, NO)) {
return frames;
}
[self->_lastFrame unlock];
self->_lastFrame = frames.lastObject;
[self->_lastFrame lock];
NSMutableArray *ret = [NSMutableArray array];
for (SGFrame *obj in frames) {
if (CMTimeCompare(obj.timeStamp, timeRange.start) < 0) {
Expand Down
3 changes: 3 additions & 0 deletions SGPlayer/Classes/Core/SGDemuxer/SGURLDemuxer.m
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ - (NSError *)seekToTime:(CMTime)time toleranceBefor:(CMTime)toleranceBefor toler
int ret = av_seek_frame(self->_context, -1, timeStamp, AVSEEK_FLAG_BACKWARD);
if (ret >= 0) {
if (CMTIME_IS_NUMERIC(toleranceBefor)) {
if (CMTimeCompare(self->_duration, kCMTimeZero) > 0) {
time = CMTimeMinimum(time, self->_duration);
}
toleranceBefor = CMTimeMaximum(toleranceBefor, kCMTimeZero);
self->_basetime = CMTimeSubtract(time, toleranceBefor);
} else {
Expand Down
3 changes: 2 additions & 1 deletion SGPlayer/Classes/SGPlayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,8 @@ - (SGBlock)infoCallback:(SGInfoAction)action
} else if (action & SGInfoActionTime) {
NSTimeInterval currentTime = CACurrentMediaTime();
NSTimeInterval interval = currentTime - self->_flags.lastNotificationTime;
if (interval >= self->_minimumTimeInfoInterval) {
if (self->_flags.playing == NO ||
interval >= self->_minimumTimeInfoInterval) {
needed = YES;
self->_flags.lastNotificationTime = currentTime;
} else {
Expand Down

0 comments on commit 18e359b

Please sign in to comment.