@@ -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 ) {
0 commit comments