@@ -30,6 +30,7 @@ pub(crate) struct DecodeScheduler<Error: Send + 'static> {
30
30
sample_rate : u32 ,
31
31
num_frames : usize ,
32
32
transport : Transport ,
33
+ decoder_current_frame_index : usize ,
33
34
decoded_chunk : Option < DecodedChunk > ,
34
35
command_consumer : HeapConsumer < DecodeSchedulerCommand > ,
35
36
frame_producer : HeapProducer < TimestampedFrame > ,
@@ -67,6 +68,7 @@ impl<Error: Send + 'static> DecodeScheduler<Error> {
67
68
sample_rate,
68
69
num_frames,
69
70
) ,
71
+ decoder_current_frame_index : 0 ,
70
72
decoded_chunk : None ,
71
73
command_consumer,
72
74
frame_producer,
@@ -141,24 +143,33 @@ impl<Error: Send + 'static> DecodeScheduler<Error> {
141
143
return Ok ( Frame :: ZERO ) ;
142
144
}
143
145
let index: usize = index. try_into ( ) . expect ( "could not convert i64 into usize" ) ;
144
- match self
145
- . decoded_chunk
146
- . as_ref ( )
147
- . and_then ( |chunk| chunk. frame_at_index ( index) )
148
- {
149
- Some ( frame) => Ok ( frame) ,
150
- None => {
151
- let new_chunk_start_index = self . decoder . seek ( index) ?;
152
- let frames = self . decoder . decode ( ) ?;
153
- let chunk = DecodedChunk {
154
- start_index : new_chunk_start_index,
155
- frames,
156
- } ;
157
- let frame = chunk
158
- . frame_at_index ( index)
159
- . expect ( "did not get expected frame after seeking decoder" ) ;
160
- self . decoded_chunk = Some ( chunk) ;
161
- Ok ( frame)
146
+ // if the requested frame is already loaded, return it
147
+ if let Some ( chunk) = & self . decoded_chunk {
148
+ if let Some ( frame) = chunk. frame_at_index ( index) {
149
+ return Ok ( frame) ;
150
+ }
151
+ }
152
+ /*
153
+ otherwise, seek to the requested index and decode chunks sequentially
154
+ until we get the frame we want. just because we seek to an index does
155
+ not mean the next decoded chunk will have the frame we want (or any frame
156
+ at all, for that matter), so we may need to decode multiple chunks to
157
+ get the frame we care about.
158
+ */
159
+ if index < self . decoder_current_frame_index {
160
+ self . decoder_current_frame_index = self . decoder . seek ( index) ?;
161
+ }
162
+ loop {
163
+ let decoded_chunk = DecodedChunk {
164
+ start_index : self . decoder_current_frame_index ,
165
+ frames : self . decoder . decode ( ) ?,
166
+ } ;
167
+ self . decoder_current_frame_index += decoded_chunk. frames . len ( ) ;
168
+ self . decoded_chunk = Some ( decoded_chunk) ;
169
+ if let Some ( chunk) = & self . decoded_chunk {
170
+ if let Some ( frame) = chunk. frame_at_index ( index) {
171
+ return Ok ( frame) ;
172
+ }
162
173
}
163
174
}
164
175
}
@@ -177,6 +188,11 @@ impl<Error: Send + 'static> DecodeScheduler<Error> {
177
188
178
189
fn seek_to_index ( & mut self , index : i64 ) -> Result < ( ) , Error > {
179
190
self . transport . seek_to ( index) ;
191
+ self . decoder_current_frame_index = self . decoder . seek ( if index < 0 {
192
+ 0
193
+ } else {
194
+ index. try_into ( ) . expect ( "could not convert i64 into usize" )
195
+ } ) ?;
180
196
Ok ( ( ) )
181
197
}
182
198
}
0 commit comments