| 172 | } |
| 173 | |
| 174 | static void |
| 175 | flac_decoder_loop(FlacDecoder *data, FLAC__StreamDecoder *flac_dec) |
| 176 | { |
| 177 | DecoderClient &client = *data->GetClient(); |
| 178 | |
| 179 | while (true) { |
| 180 | DecoderCommand cmd = FlacSubmitToClient(client, *data); |
| 181 | |
| 182 | if (cmd == DecoderCommand::SEEK) { |
| 183 | FLAC__uint64 seek_sample = client.GetSeekFrame(); |
| 184 | if (FLAC__stream_decoder_seek_absolute(flac_dec, seek_sample)) { |
| 185 | data->position = 0; |
| 186 | client.CommandFinished(); |
| 187 | } else |
| 188 | client.SeekError(); |
| 189 | |
| 190 | /* FLAC__stream_decoder_seek_absolute() |
| 191 | decodes one frame and may have provided |
| 192 | data to be submitted to the client */ |
| 193 | continue; |
| 194 | } else if (cmd == DecoderCommand::STOP) |
| 195 | break; |
| 196 | |
| 197 | switch (FLAC__stream_decoder_get_state(flac_dec)) { |
| 198 | case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: |
| 199 | case FLAC__STREAM_DECODER_READ_METADATA: |
| 200 | case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: |
| 201 | case FLAC__STREAM_DECODER_READ_FRAME: |
| 202 | /* continue decoding */ |
| 203 | break; |
| 204 | |
| 205 | case FLAC__STREAM_DECODER_END_OF_STREAM: |
| 206 | /* regular end of stream */ |
| 207 | return; |
| 208 | |
| 209 | case FLAC__STREAM_DECODER_SEEK_ERROR: |
| 210 | /* try to recover from seek error */ |
| 211 | if (!FLAC__stream_decoder_flush(flac_dec)) { |
| 212 | LogError(flac_domain, "FLAC__stream_decoder_flush() failed"); |
| 213 | return; |
| 214 | } |
| 215 | |
| 216 | break; |
| 217 | |
| 218 | case FLAC__STREAM_DECODER_OGG_ERROR: |
| 219 | case FLAC__STREAM_DECODER_ABORTED: |
| 220 | case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR: |
| 221 | /* an error, fatal enough for us to abort the |
| 222 | decoder */ |
| 223 | return; |
| 224 | |
| 225 | case FLAC__STREAM_DECODER_UNINITIALIZED: |
| 226 | /* we shouldn't see this, ever - bail out */ |
| 227 | return; |
| 228 | |
| 229 | #if FLAC_API_VERSION_CURRENT >= 14 |
| 230 | case FLAC__STREAM_DECODER_END_OF_LINK: |
| 231 | if (!FLAC__stream_decoder_finish_link(flac_dec)) { |
no test coverage detected