Skip to content

Commit

Permalink
SGAudioFormatter: Add finish func.
Browse files Browse the repository at this point in the history
  • Loading branch information
libobjc committed Nov 1, 2019
1 parent 7db8f9f commit 25843ac
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
5 changes: 5 additions & 0 deletions SGPlayer/Classes/Core/SGProcessor/SGAudioFormatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
*/
- (SGAudioFrame *)format:(SGAudioFrame *)frame;

/**
*
*/
- (SGAudioFrame *)finish;

/**
*
*/
Expand Down
53 changes: 42 additions & 11 deletions SGPlayer/Classes/Core/SGProcessor/SGAudioFormatter.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,22 @@

@interface SGAudioFormatter ()

@property (nonatomic, readonly) SGTrack *track;
@property (nonatomic, readonly) CMTime nextTimeStamp;
@property (nonatomic, strong, readonly) SGSWResample *context;

@end

@implementation SGAudioFormatter

- (instancetype)init
{
if (self = [super init]) {
[self flush];
}
return self;
}

- (SGAudioFrame *)format:(SGAudioFrame *)frame
{
if (![frame isKindOfClass:[SGAudioFrame class]]) {
Expand All @@ -26,7 +36,7 @@ - (SGAudioFrame *)format:(SGAudioFrame *)frame
}
if (![self->_context.inputDescriptor isEqualToDescriptor:frame.descriptor] ||
![self->_context.outputDescriptor isEqualToDescriptor:self->_descriptor]) {
self->_context = nil;
[self flush];
SGSWResample *context = [[SGSWResample alloc] init];
context.inputDescriptor = frame.descriptor;
context.outputDescriptor = self->_descriptor;
Expand All @@ -38,27 +48,48 @@ - (SGAudioFrame *)format:(SGAudioFrame *)frame
[frame unlock];
return nil;
}
int nb_planes = self->_descriptor.numberOfPlanes;
self->_track = frame.track;
int nb_samples = [self->_context write:frame.data nb_samples:frame.numberOfSamples];
CMTime start = frame.timeStamp;
CMTime duration = CMTimeMake(nb_samples, self->_descriptor.sampleRate);
SGAudioFrame *ret = [SGAudioFrame audioFrameWithDescriptor:self->_descriptor numberOfSamples:nb_samples];
SGAudioFrame *ret = [self frameWithStart:frame.timeStamp nb_samples:nb_samples];
self->_nextTimeStamp = CMTimeAdd(ret.timeStamp, ret.duration);
[frame unlock];
return ret;
}

- (SGAudioFrame *)finish
{
if (!self->_track || !self->_context || CMTIME_IS_INVALID(self->_nextTimeStamp)) {
return nil;
}
int nb_samples = [self->_context write:NULL nb_samples:0];
if (nb_samples <= 0) {
return nil;
}
SGAudioFrame *frame = [self frameWithStart:self->_nextTimeStamp nb_samples:nb_samples];
return frame;
}

- (SGAudioFrame *)frameWithStart:(CMTime)start nb_samples:(int)nb_samples
{
SGAudioFrame *frame = [SGAudioFrame audioFrameWithDescriptor:self->_descriptor numberOfSamples:nb_samples];
uint8_t nb_planes = self->_descriptor.numberOfPlanes;
uint8_t *data[SGFramePlaneCount] = {NULL};
for (int i = 0; i < nb_planes; i++) {
data[i] = ret.core->data[i];
data[i] = frame.core->data[i];
}
[self->_context read:data nb_samples:nb_samples];
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
cd.track = frame.track;
[ret setCodecDescriptor:cd];
[ret fillWithTimeStamp:start decodeTimeStamp:start duration:duration];
[frame unlock];
return ret;
cd.track = self->_track;
[frame setCodecDescriptor:cd];
[frame fillWithTimeStamp:start decodeTimeStamp:start duration:CMTimeMake(nb_samples, self->_descriptor.sampleRate)];
return frame;
}

- (void)flush
{
self->_track = nil;
self->_context = nil;
self->_nextTimeStamp = kCMTimeInvalid;
}

@end
5 changes: 5 additions & 0 deletions SGPlayer/Classes/Core/SGProcessor/SGSWResample.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@
*/
- (int)read:(uint8_t **)data nb_samples:(int)nb_samples;

/**
*
*/
- (int)delay;

@end
7 changes: 7 additions & 0 deletions SGPlayer/Classes/Core/SGProcessor/SGSWResample.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,11 @@ - (int)read:(uint8_t **)data nb_samples:(int)nb_samples
return nb_samples;
}

- (int)delay
{
int64_t delay = swr_get_delay(self->_context, self->_outputDescriptor.sampleRate);
NSAssert(delay < INT32_MAX, @"Invalid ");
return (int)delay;
}

@end

0 comments on commit 25843ac

Please sign in to comment.