Skip to content

Commit

Permalink
SGVideoDecoder: Resample.
Browse files Browse the repository at this point in the history
  • Loading branch information
libobjc committed Nov 28, 2019
1 parent 5f560a9 commit 15e6ad1
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 47 deletions.
38 changes: 19 additions & 19 deletions SGPlayer/Classes/Core/SGDecoder/SGAudioDecoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ - (void)flush

- (NSArray<__kindof SGFrame *> *)decode:(SGPacket *)packet
{
NSMutableArray *ret = [NSMutableArray array];
NSMutableArray *frames = [NSMutableArray array];
SGCodecDescriptor *cd = packet.codecDescriptor;
NSAssert(cd, @"Invalid codec descriptor.");
BOOL isEqual = [cd isEqualToDescriptor:self->_codecDescriptor];
BOOL isEqualCodec = [cd isEqualCodecContextToDescriptor:self->_codecDescriptor];
if (!isEqual) {
NSArray<SGFrame *> *objs = [self finish];
for (SGFrame *obj in objs) {
[ret addObject:obj];
[frames addObject:obj];
}
self->_codecDescriptor = [cd copy];
if (isEqualCodec) {
Expand All @@ -118,26 +118,26 @@ - (void)flush
cd.metadata = packet.metadata;
[obj setCodecDescriptor:cd];
[obj fillWithTimeStamp:start decodeTimeStamp:start duration:duration];
[ret addObject:obj];
[frames addObject:obj];
}
} else {
NSArray<SGFrame *> *objs = [self processPacket:packet];
for (SGFrame *obj in objs) {
[ret addObject:obj];
[frames addObject:obj];
}
}
if (ret.count > 0) {
SGFrame *obj = ret.lastObject;
if (frames.count > 0) {
SGFrame *obj = frames.lastObject;
self->_flags.lastEndTimeStamp = CMTimeAdd(obj.timeStamp, obj.duration);
}
return ret;
return frames;
}

- (NSArray<__kindof SGFrame *> *)finish
{
NSArray<SGFrame *> *objs = [self processPacket:nil];
if (objs.count > 0) {
self->_flags.lastEndTimeStamp = CMTimeAdd(objs.lastObject.timeStamp, objs.lastObject.duration);
NSArray<SGFrame *> *frames = [self processPacket:nil];
if (frames.count > 0) {
self->_flags.lastEndTimeStamp = CMTimeAdd(frames.lastObject.timeStamp, frames.lastObject.duration);
}
CMTime lastEnd = self->_flags.lastEndTimeStamp;
CMTimeRange timeRange = self->_codecDescriptor.timeRange;
Expand All @@ -156,12 +156,12 @@ - (void)flush
cd.metadata = self->_codecDescriptor.metadata;
[obj setCodecDescriptor:cd];
[obj fillWithTimeStamp:lastEnd decodeTimeStamp:lastEnd duration:duration];
NSMutableArray<SGFrame *> *newObjs = [NSMutableArray arrayWithArray:objs];
[newObjs addObject:obj];
objs = [newObjs copy];
NSMutableArray<SGFrame *> *newFrames = [NSMutableArray arrayWithArray:frames];
[newFrames addObject:obj];
frames = [newFrames copy];
}
}
return objs;
return frames;
}

#pragma mark - Process
Expand All @@ -172,11 +172,11 @@ - (void)flush
return nil;
}
SGCodecDescriptor *cd = self->_codecDescriptor;
NSArray *objs = [self->_codecContext decode:packet];
objs = [self processFrames:objs done:!packet];
objs = [self clipFrames:objs timeRange:cd.timeRange];
objs = [self formatFrames:objs];
return objs;
NSArray *frames = [self->_codecContext decode:packet];
frames = [self processFrames:frames done:!packet];
frames = [self clipFrames:frames timeRange:cd.timeRange];
frames = [self formatFrames:frames];
return frames;
}

- (NSArray<__kindof SGFrame *> *)processFrames:(NSArray<__kindof SGFrame *> *)frames done:(BOOL)done
Expand Down
64 changes: 36 additions & 28 deletions SGPlayer/Classes/Core/SGDecoder/SGVideoDecoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,15 @@ - (void)flush

- (NSArray<__kindof SGFrame *> *)decode:(SGPacket *)packet
{
NSMutableArray *ret = [NSMutableArray array];
NSMutableArray *frames = [NSMutableArray array];
SGCodecDescriptor *cd = packet.codecDescriptor;
NSAssert(cd, @"Invalid Codec Descriptor.");
BOOL isEqual = [cd isEqualToDescriptor:self->_codecDescriptor];
BOOL isEqualCodec = [cd isEqualCodecContextToDescriptor:self->_codecDescriptor];
if (!isEqual) {
NSArray<SGFrame *> *objs = [self finish];
for (SGFrame *obj in objs) {
[ret addObject:obj];
[frames addObject:obj];
}
self->_codecDescriptor = [cd copy];
if (isEqualCodec) {
Expand All @@ -119,9 +119,10 @@ - (void)flush
} else {
NSArray<SGFrame *> *objs = [self processPacket:packet];
for (SGFrame *obj in objs) {
[ret addObject:obj];
[frames addObject:obj];
}
}
NSArray *ret = [self resampleFrames:frames];
if (ret.lastObject) {
[self->_lastOutputFrame unlock];
self->_lastOutputFrame = ret.lastObject;
Expand All @@ -133,14 +134,14 @@ - (void)flush

- (NSArray<__kindof SGFrame *> *)finish
{
NSArray<SGFrame *> *objs = [self processPacket:nil];
if (objs.count == 0 &&
NSArray<SGFrame *> *frames = [self processPacket:nil];
if (frames.count == 0 &&
self->_lastDecodeFrame &&
self->_flags.outputCount == 0) {
self->_lastDecodeFrame.flags |= SGDataFlagPadding;
objs = @[self->_lastDecodeFrame];
frames = @[self->_lastDecodeFrame];
[self->_lastDecodeFrame lock];
} else if (objs.count == 0 &&
} else if (frames.count == 0 &&
self->_lastOutputFrame) {
CMTimeRange timeRange = self->_codecDescriptor.timeRange;
if (CMTIME_IS_NUMERIC(timeRange.start) &&
Expand All @@ -149,38 +150,40 @@ - (void)flush
CMTime lastEnd = CMTimeAdd(self->_lastOutputFrame.timeStamp, self->_lastOutputFrame.duration);
CMTime duration = CMTimeSubtract(end, lastEnd);
if (CMTimeCompare(duration, kCMTimeZero) > 0) {
SGVideoFrame *frame = [SGVideoFrame frame];
[frame fillWithFrame:self->_lastOutputFrame];
SGVideoFrame *obj = [SGVideoFrame frame];
[obj fillWithFrame:self->_lastOutputFrame];
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
cd.track = frame.track;
cd.metadata = frame.codecDescriptor.metadata;
[frame setCodecDescriptor:cd];
[frame fillWithTimeStamp:lastEnd decodeTimeStamp:lastEnd duration:duration];
objs = @[frame];
cd.track = obj.track;
cd.metadata = obj.codecDescriptor.metadata;
[obj setCodecDescriptor:cd];
[obj fillWithTimeStamp:lastEnd decodeTimeStamp:lastEnd duration:duration];
frames = @[obj];
}
}
} else if (objs.count > 0) {
} else if (frames.count > 0) {
CMTimeRange timeRange = self->_codecDescriptor.timeRange;
if (CMTIME_IS_NUMERIC(timeRange.start) &&
CMTIME_IS_NUMERIC(timeRange.duration)) {
SGFrame *obj = frames.lastObject;
CMTime end = CMTimeRangeGetEnd(timeRange);
CMTime lastEnd = CMTimeAdd(objs.lastObject.timeStamp, objs.lastObject.duration);
CMTime lastEnd = CMTimeAdd(obj.timeStamp, obj.duration);
CMTime duration = CMTimeSubtract(end, lastEnd);
if (CMTimeCompare(duration, kCMTimeZero) > 0) {
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
cd.track = objs.lastObject.track;
cd.metadata = objs.lastObject.codecDescriptor.metadata;
[objs.lastObject setCodecDescriptor:cd];
[objs.lastObject fillWithTimeStamp:objs.lastObject.timeStamp decodeTimeStamp:objs.lastObject.timeStamp duration:CMTimeSubtract(end, objs.lastObject.timeStamp)];
cd.track = obj.track;
cd.metadata = obj.codecDescriptor.metadata;
[obj setCodecDescriptor:cd];
[obj fillWithTimeStamp:obj.timeStamp decodeTimeStamp:obj.timeStamp duration:CMTimeSubtract(end, obj.timeStamp)];
}
}
}
[self->_lastDecodeFrame unlock];
self->_lastDecodeFrame = nil;
[self->_lastOutputFrame unlock];
self->_lastOutputFrame = nil;
self->_flags.outputCount += objs.count;
return objs;
NSArray *ret = [self resampleFrames:frames];
self->_flags.outputCount += ret.count;
return ret;
}

#pragma mark - Process
Expand All @@ -191,12 +194,12 @@ - (void)flush
return nil;
}
SGCodecDescriptor *cd = self->_codecDescriptor;
NSArray *objs = [self->_codecContext decode:packet];
objs = [self processFrames:objs done:!packet];
objs = [self clipKeyFrames:objs];
objs = [self clipFrames:objs timeRange:cd.timeRange];
objs = [self formatFrames:objs];
return objs;
NSArray *frames = [self->_codecContext decode:packet];
frames = [self processFrames:frames done:!packet];
frames = [self clipKeyFrames:frames];
frames = [self clipFrames:frames timeRange:cd.timeRange];
frames = [self formatFrames:frames];
return frames;
}

- (NSArray<__kindof SGFrame *> *)processFrames:(NSArray<__kindof SGFrame *> *)frames done:(BOOL)done
Expand Down Expand Up @@ -335,4 +338,9 @@ - (void)flush
return ret;
}

- (NSArray<__kindof SGFrame *> *)resampleFrames:(NSArray<__kindof SGFrame *> *)frames
{
return frames;
}

@end
17 changes: 17 additions & 0 deletions SGPlayer/Classes/Core/SGOption/SGDecoderOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import <Foundation/Foundation.h>
#import "SGAudioDescriptor.h"
#import "SGTime.h"

@interface SGDecoderOptions : NSObject <NSCopying>

Expand Down Expand Up @@ -73,4 +74,20 @@
*/
@property (nonatomic, copy) NSArray<SGAudioDescriptor *> *supportedAudioDescriptors;

/*!
@property resetFrameRate
@abstract
Indicates whether video decoder needs reset frame rate.
Default is NO.
*/
@property (nonatomic) BOOL resetFrameRate;

/*!
@property preferredFrameRate
@abstract
Indicates the preferred video track frame rate.
Default is (1, 25).
*/
@property (nonatomic) CMTime preferredFrameRate;

@end
4 changes: 4 additions & 0 deletions SGPlayer/Classes/Core/SGOption/SGDecoderOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ - (id)copyWithZone:(NSZone *)zone
obj->_preferredPixelFormat = self->_preferredPixelFormat;
obj->_supportedPixelFormats = self->_supportedPixelFormats.copy;
obj->_supportedAudioDescriptors = self->_supportedAudioDescriptors.copy;
obj->_resetFrameRate = self->_resetFrameRate;
obj->_preferredFrameRate = self->_preferredFrameRate;
return obj;
}

Expand All @@ -38,6 +40,8 @@ - (instancetype)init
self->_preferredPixelFormat = SGPixelFormatFF2AV(AV_PIX_FMT_NV12);
self->_supportedPixelFormats = [SGVideoRenderer supportedPixelFormats];
self->_supportedAudioDescriptors = @[[SGAudioRenderer supportedAudioDescriptor]];
self->_resetFrameRate = NO;
self->_preferredFrameRate = CMTimeMake(1, 25);
}
return self;
}
Expand Down

0 comments on commit 15e6ad1

Please sign in to comment.