Skip to content

Commit fcc7a9e

Browse files
committed
Update MultiFrameImageStreamCompleter
1 parent 1df55ab commit fcc7a9e

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

cached_network_image/lib/src/image_provider/multi_image_stream_completer.dart

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class MultiImageStreamCompleter extends ImageStreamCompleter {
1818
MultiImageStreamCompleter({
1919
required Stream<ui.Codec> codec,
2020
required double scale,
21+
String? debugLabel,
2122
Stream<ImageChunkEvent>? chunkEvents,
2223
InformationCollector? informationCollector,
2324
}) : _informationCollector = informationCollector,
@@ -63,7 +64,7 @@ class MultiImageStreamCompleter extends ImageStreamCompleter {
6364
ui.FrameInfo? _nextFrame;
6465

6566
// When the current was first shown.
66-
Duration? _shownTimestamp;
67+
late Duration _shownTimestamp;
6768

6869
// The requested duration for the current frame;
6970
Duration? _frameDuration;
@@ -99,25 +100,36 @@ class MultiImageStreamCompleter extends ImageStreamCompleter {
99100

100101
void _handleAppFrame(Duration timestamp) {
101102
_frameCallbackScheduled = false;
102-
if (!hasListeners) return;
103+
if (!hasListeners) {
104+
return;
105+
}
106+
assert(_nextFrame != null);
103107
if (_isFirstFrame() || _hasFrameDurationPassed(timestamp)) {
104-
_emitFrame(ImageInfo(image: _nextFrame!.image, scale: _scale));
108+
_emitFrame(ImageInfo(
109+
image: _nextFrame!.image.clone(),
110+
scale: _scale,
111+
debugLabel: debugLabel,
112+
));
105113
_shownTimestamp = timestamp;
106114
_frameDuration = _nextFrame!.duration;
115+
_nextFrame!.image.dispose();
107116
_nextFrame = null;
117+
108118
if (_framesEmitted % _codec!.frameCount == 0 && _nextImageCodec != null) {
109119
_switchToNewCodec();
110120
} else {
111-
final completedCycles = _framesEmitted ~/ _codec!.frameCount;
121+
final int completedCycles = _framesEmitted ~/ _codec!.frameCount;
112122
if (_codec!.repetitionCount == -1 ||
113123
completedCycles <= _codec!.repetitionCount) {
114124
_decodeNextFrameAndSchedule();
115125
}
116126
}
117127
return;
118128
}
119-
final delay = _frameDuration! - (timestamp - _shownTimestamp!);
120-
_timer = Timer(delay * timeDilation, _scheduleAppFrame);
129+
final Duration delay = _frameDuration! - (timestamp - _shownTimestamp);
130+
_timer = Timer(delay * timeDilation, () {
131+
_scheduleAppFrame();
132+
});
121133
}
122134

123135
bool _isFirstFrame() {
@@ -129,9 +141,13 @@ class MultiImageStreamCompleter extends ImageStreamCompleter {
129141
}
130142

131143
Future<void> _decodeNextFrameAndSchedule() async {
144+
// This will be null if we gave it away. If not, it's still ours and it
145+
// must be disposed of.
146+
_nextFrame?.image.dispose();
147+
_nextFrame = null;
132148
try {
133149
_nextFrame = await _codec!.getNextFrame();
134-
} on Object catch (exception, stack) {
150+
} catch (exception, stack) {
135151
reportError(
136152
context: ErrorDescription('resolving an image frame'),
137153
exception: exception,
@@ -148,10 +164,15 @@ class MultiImageStreamCompleter extends ImageStreamCompleter {
148164
if (!hasListeners) {
149165
return;
150166
}
151-
152167
// This is not an animated image, just return it and don't schedule more
153168
// frames.
154-
_emitFrame(ImageInfo(image: _nextFrame!.image, scale: _scale));
169+
_emitFrame(ImageInfo(
170+
image: _nextFrame!.image.clone(),
171+
scale: _scale,
172+
debugLabel: debugLabel,
173+
));
174+
_nextFrame!.image.dispose();
175+
_nextFrame = null;
155176
return;
156177
}
157178
_scheduleAppFrame();
@@ -173,7 +194,12 @@ class MultiImageStreamCompleter extends ImageStreamCompleter {
173194
@override
174195
void addListener(ImageStreamListener listener) {
175196
__hadAtLeastOneListener = true;
176-
if (!hasListeners && _codec != null) _decodeNextFrameAndSchedule();
197+
if (!hasListeners &&
198+
_codec != null &&
199+
( //_currentImage == null ||
200+
_codec!.frameCount > 1)) {
201+
_decodeNextFrameAndSchedule();
202+
}
177203
super.addListener(listener);
178204
}
179205

cached_network_image/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ dependencies:
1616
cached_network_image_web: ^1.1.1
1717
flutter:
1818
sdk: flutter
19-
flutter_cache_manager: ^3.3.1
19+
flutter_cache_manager: ^3.3.2
2020
octo_image: ^2.0.0
2121

2222
dev_dependencies:

0 commit comments

Comments
 (0)