Skip to content

Commit 472d6cd

Browse files
committed
SGDecoder: Alignment.
1 parent 6cb8c2b commit 472d6cd

5 files changed

Lines changed: 110 additions & 22 deletions

File tree

SGPlayer/Classes/Core/SGCommon/SGTime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ CMTime SGCMTimeMultiply(CMTime time, CMTime multiplier);
1717
CMTime SGCMTimeDivide(CMTime time, CMTime divisor);
1818
CMTime SGCMTimeDivide(CMTime time, CMTime divisor);
1919

20-
CMTimeRange SGCMTimeRangeFit(CMTimeRange timeRange);
20+
CMTimeRange SGCMTimeRangeFitting(CMTimeRange timeRange);
2121
CMTimeRange SGCMTimeRangeGetIntersection(CMTimeRange timeRange1, CMTimeRange timeRange2);

SGPlayer/Classes/Core/SGCommon/SGTime.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ CMTime SGCMTimeDivide(CMTime time, CMTime divisor)
5151
return CMTimeMake(time.value * divisor.timescale, time.timescale * (int32_t)divisor.value);
5252
}
5353

54-
CMTimeRange SGCMTimeRangeFit(CMTimeRange timeRange)
54+
CMTimeRange SGCMTimeRangeFitting(CMTimeRange timeRange)
5555
{
5656
return CMTimeRangeMake(SGCMTimeValidate(timeRange.start, kCMTimeNegativeInfinity, YES),
5757
SGCMTimeValidate(timeRange.duration, kCMTimePositiveInfinity, YES));

SGPlayer/Classes/Core/SGDecoder/SGAudioDecoder.m

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ @interface SGAudioDecoder ()
2121
BOOL needsAlignment;
2222
BOOL needsResetSonic;
2323
int64_t nextTimeStamp;
24+
CMTime lastEndTimeStamp;
2425
} _flags;
2526
}
2627

@@ -59,6 +60,7 @@ - (void)destroy
5960
self->_flags.nextTimeStamp = 0;
6061
self->_flags.needsAlignment = YES;
6162
self->_flags.needsResetSonic = YES;
63+
self->_flags.lastEndTimeStamp = kCMTimeInvalid;
6264
[self->_codecContext close];
6365
self->_codecContext = nil;
6466
self->_audioDescriptor = nil;
@@ -71,12 +73,13 @@ - (void)flush
7173
self->_flags.nextTimeStamp = 0;
7274
self->_flags.needsAlignment = YES;
7375
self->_flags.needsResetSonic = YES;
76+
self->_flags.lastEndTimeStamp = kCMTimeInvalid;
7477
[self->_codecContext flush];
7578
}
7679

7780
- (NSArray<__kindof SGFrame *> *)decode:(SGPacket *)packet
7881
{
79-
NSMutableArray *ret = [NSMutableArray array];
82+
NSMutableArray<__kindof SGFrame *> *ret = [NSMutableArray array];
8083
SGCodecDescriptor *cd = packet.codecDescriptor;
8184
NSAssert(cd, @"Invalid codec descriptor.");
8285
if (![cd isEqualCodecContextToDescriptor:self->_codecDescriptor]) {
@@ -102,6 +105,7 @@ - (void)flush
102105
SGAudioFrame *obj = [SGAudioFrame frameWithDescriptor:ad numberOfSamples:nb_samples];
103106
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
104107
cd.track = packet.track;
108+
cd.metadata = packet.metadata;
105109
[obj setCodecDescriptor:cd];
106110
[obj fillWithTimeStamp:start decodeTimeStamp:start duration:duration];
107111
[ret addObject:obj];
@@ -112,12 +116,41 @@ - (void)flush
112116
[ret addObject:obj];
113117
}
114118
}
119+
if (ret.count) {
120+
self->_flags.lastEndTimeStamp = CMTimeAdd(ret.lastObject.timeStamp, ret.lastObject.duration);
121+
}
115122
return ret;
116123
}
117124

118125
- (NSArray<__kindof SGFrame *> *)finish
119126
{
120-
return [self processPacket:nil];
127+
NSArray<SGFrame *> *objs = [self processPacket:nil];
128+
if (objs.count > 0) {
129+
self->_flags.lastEndTimeStamp = CMTimeAdd(objs.lastObject.timeStamp, objs.lastObject.duration);
130+
}
131+
CMTime lastEnd = self->_flags.lastEndTimeStamp;
132+
CMTimeRange timeRange = self->_codecDescriptor.timeRange;
133+
if (CMTIME_IS_NUMERIC(lastEnd) &&
134+
CMTIME_IS_NUMERIC(timeRange.start) &&
135+
CMTIME_IS_NUMERIC(timeRange.duration)) {
136+
CMTime end = CMTimeRangeGetEnd(timeRange);
137+
CMTime duration = CMTimeSubtract(end, lastEnd);
138+
SGAudioDescriptor *ad = self->_audioDescriptor;
139+
int nb_samples = (int)CMTimeConvertScale(duration, ad.sampleRate, kCMTimeRoundingMethod_RoundTowardZero).value;
140+
if (nb_samples > 0) {
141+
duration = CMTimeMake(nb_samples, ad.sampleRate);
142+
SGAudioFrame *obj = [SGAudioFrame frameWithDescriptor:ad numberOfSamples:nb_samples];
143+
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
144+
cd.track = self->_codecDescriptor.track;
145+
cd.metadata = self->_codecDescriptor.metadata;
146+
[obj setCodecDescriptor:cd];
147+
[obj fillWithTimeStamp:lastEnd decodeTimeStamp:lastEnd duration:duration];
148+
NSMutableArray<SGFrame *> *newObjs = [NSMutableArray arrayWithArray:objs];
149+
[newObjs addObject:obj];
150+
objs = [newObjs copy];
151+
}
152+
}
153+
return objs;
121154
}
122155

123156
#pragma mark - Process
@@ -136,7 +169,7 @@ - (void)flush
136169

137170
- (NSArray<__kindof SGFrame *> *)processFrames:(NSArray<__kindof SGFrame *> *)frames done:(BOOL)done
138171
{
139-
NSMutableArray *ret = [NSMutableArray array];
172+
NSMutableArray<__kindof SGFrame *> *ret = [NSMutableArray array];
140173
for (SGAudioFrame *obj in frames) {
141174
AVFrame *frame = obj.core;
142175
if (self->_audioDescriptor == nil) {
@@ -206,6 +239,7 @@ - (void)flush
206239
SGAudioFrame *obj1 = [SGAudioFrame frameWithDescriptor:ad numberOfSamples:nb_samples];
207240
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
208241
cd.track = obj.track;
242+
cd.metadata = obj.metadata;
209243
[obj1 setCodecDescriptor:cd];
210244
[obj1 fillWithTimeStamp:start decodeTimeStamp:start duration:duration];
211245
[ret addObject:obj1];
@@ -223,6 +257,7 @@ - (void)flush
223257
}
224258
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
225259
cd.track = obj.track;
260+
cd.metadata = obj.metadata;
226261
[obj1 setCodecDescriptor:cd];
227262
[obj1 fillWithTimeStamp:start decodeTimeStamp:start duration:duration];
228263
[ret addObject:obj1];
@@ -247,6 +282,7 @@ - (SGAudioFrame *)readSonicFrame:(int64_t)pts
247282
[self->_sonic read:obj.core->data nb_samples:nb_samples];
248283
SGCodecDescriptor *cd1 = [[SGCodecDescriptor alloc] init];
249284
cd1.track = cd.track;
285+
cd1.metadata = cd.metadata;
250286
[obj setCodecDescriptor:cd1];
251287
[obj fillWithTimeStamp:start decodeTimeStamp:start duration:duration];
252288
return obj;

SGPlayer/Classes/Core/SGDecoder/SGVideoDecoder.m

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ @interface SGVideoDecoder ()
2222
} _flags;
2323
}
2424

25-
@property (nonatomic, strong, readonly) SGVideoFrame *lastFrame;
25+
@property (nonatomic, strong, readonly) SGVideoFrame *lastDecodeFrame;
26+
@property (nonatomic, strong, readonly) SGVideoFrame *lastOutputFrame;
2627
@property (nonatomic, strong, readonly) SGDecodeContext *codecContext;
2728
@property (nonatomic, strong, readonly) SGCodecDescriptor *codecDescriptor;
2829

@@ -64,8 +65,10 @@ - (void)destroy
6465
self->_flags.needsAlignment = YES;
6566
[self->_codecContext close];
6667
self->_codecContext = nil;
67-
[self->_lastFrame unlock];
68-
self->_lastFrame = nil;
68+
[self->_lastDecodeFrame unlock];
69+
self->_lastDecodeFrame = nil;
70+
[self->_lastOutputFrame unlock];
71+
self->_lastOutputFrame = nil;
6972
}
7073

7174
#pragma mark - Control
@@ -76,8 +79,10 @@ - (void)flush
7679
self->_flags.needsKeyFrame = YES;
7780
self->_flags.needsAlignment = YES;
7881
[self->_codecContext flush];
79-
[self->_lastFrame unlock];
80-
self->_lastFrame = nil;
82+
[self->_lastDecodeFrame unlock];
83+
self->_lastDecodeFrame = nil;
84+
[self->_lastOutputFrame unlock];
85+
self->_lastOutputFrame = nil;
8186
}
8287

8388
- (NSArray<__kindof SGFrame *> *)decode:(SGPacket *)packet
@@ -103,6 +108,11 @@ - (void)flush
103108
[ret addObject:obj];
104109
}
105110
}
111+
if (ret.firstObject) {
112+
[self->_lastOutputFrame unlock];
113+
self->_lastOutputFrame = ret.firstObject;
114+
[self->_lastOutputFrame lock];
115+
}
106116
self->_flags.outputCount += ret.count;
107117
return ret;
108118
}
@@ -111,14 +121,50 @@ - (void)flush
111121
{
112122
NSArray<SGFrame *> *objs = [self processPacket:nil];
113123
if (objs.count == 0 &&
114-
self->_lastFrame &&
124+
self->_lastDecodeFrame &&
115125
self->_flags.outputCount == 0) {
116-
self->_lastFrame.flags |= SGDataFlagPadding;
117-
objs = @[self->_lastFrame];
118-
} else {
119-
[self->_lastFrame unlock];
126+
self->_lastDecodeFrame.flags |= SGDataFlagPadding;
127+
objs = @[self->_lastDecodeFrame];
128+
[self->_lastDecodeFrame lock];
129+
} else if (objs.count == 0 &&
130+
self->_lastOutputFrame) {
131+
CMTimeRange timeRange = self->_codecDescriptor.timeRange;
132+
if (CMTIME_IS_NUMERIC(timeRange.start) &&
133+
CMTIME_IS_NUMERIC(timeRange.duration)) {
134+
CMTime end = CMTimeRangeGetEnd(timeRange);
135+
CMTime lastEnd = CMTimeAdd(self->_lastOutputFrame.timeStamp, self->_lastOutputFrame.duration);
136+
CMTime duration = CMTimeSubtract(end, lastEnd);
137+
if (CMTimeCompare(duration, kCMTimeZero) > 0) {
138+
SGVideoFrame *frame = [SGVideoFrame frame];
139+
[frame fillWithFrame:self->_lastOutputFrame];
140+
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
141+
cd.track = frame.track;
142+
cd.metadata = frame.codecDescriptor.metadata;
143+
[frame setCodecDescriptor:cd];
144+
[frame fillWithTimeStamp:lastEnd decodeTimeStamp:lastEnd duration:duration];
145+
objs = @[frame];
146+
}
147+
}
148+
} else if (objs.count > 0) {
149+
CMTimeRange timeRange = self->_codecDescriptor.timeRange;
150+
if (CMTIME_IS_NUMERIC(timeRange.start) &&
151+
CMTIME_IS_NUMERIC(timeRange.duration)) {
152+
CMTime end = CMTimeRangeGetEnd(timeRange);
153+
CMTime lastEnd = CMTimeAdd(objs.lastObject.timeStamp, objs.lastObject.duration);
154+
CMTime duration = CMTimeSubtract(end, lastEnd);
155+
if (CMTimeCompare(duration, kCMTimeZero) > 0) {
156+
SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
157+
cd.track = objs.lastObject.track;
158+
cd.metadata = objs.lastObject.codecDescriptor.metadata;
159+
[objs.lastObject setCodecDescriptor:cd];
160+
[objs.lastObject fillWithTimeStamp:objs.lastObject.timeStamp decodeTimeStamp:objs.lastObject.timeStamp duration:CMTimeSubtract(end, objs.lastObject.timeStamp)];
161+
}
162+
}
120163
}
121-
self->_lastFrame = nil;
164+
[self->_lastDecodeFrame unlock];
165+
self->_lastDecodeFrame = nil;
166+
[self->_lastOutputFrame unlock];
167+
self->_lastOutputFrame = nil;
122168
self->_flags.outputCount += objs.count;
123169
return objs;
124170
}
@@ -177,9 +223,9 @@ - (void)flush
177223
if (!SGCMTimeIsValid(timeRange.start, NO)) {
178224
return frames;
179225
}
180-
[self->_lastFrame unlock];
181-
self->_lastFrame = frames.lastObject;
182-
[self->_lastFrame lock];
226+
[self->_lastDecodeFrame unlock];
227+
self->_lastDecodeFrame = frames.lastObject;
228+
[self->_lastDecodeFrame lock];
183229
NSMutableArray *ret = [NSMutableArray array];
184230
for (SGFrame *obj in frames) {
185231
if (CMTimeCompare(obj.timeStamp, timeRange.start) < 0) {

SGPlayer/Classes/Core/SGDemuxer/SGExtractingDemuxer.m

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ - (instancetype)initWithDemuxable:(id<SGDemuxable>)demuxable index:(NSInteger)in
4141
self->_scale = scale;
4242
self->_index = index;
4343
self->_demuxable = demuxable;
44-
self->_timeRange = SGCMTimeRangeFit(timeRange);
44+
self->_timeRange = SGCMTimeRangeFitting(timeRange);
4545
self->_packetQueue = [[SGObjectQueue alloc] init];
4646
}
4747
return self;
@@ -72,8 +72,14 @@ - (NSError *)open
7272
break;
7373
}
7474
}
75-
CMTime start = CMTimeMaximum(self->_timeRange.start, kCMTimeZero);
76-
CMTime duration = CMTimeMinimum(self->_timeRange.duration, CMTimeSubtract(self->_demuxable.duration, start));
75+
CMTime start = self->_timeRange.start;
76+
if (!CMTIME_IS_NUMERIC(start)) {
77+
start = kCMTimeZero;
78+
}
79+
CMTime duration = self->_timeRange.duration;
80+
if (!CMTIME_IS_NUMERIC(duration)) {
81+
duration = CMTimeSubtract(self->_demuxable.duration, start);
82+
}
7783
self->_timeRange = CMTimeRangeMake(start, duration);
7884
self->_duration = SGCMTimeMultiply(duration, self->_scale);
7985
self->_scaleLayout = [[SGTimeLayout alloc] initWithScale:self->_scale];

0 commit comments

Comments
 (0)