+ switch (_flush_state) {
+ case FlushState::CODECS:
+ if (flush_codecs() == FlushResult::DONE) {
+ LOG_DEBUG_PLAYER_NC("Finished flushing codecs");
+ _flush_state = FlushState::AUDIO_DECODER;
+ }
+ break;
+ case FlushState::AUDIO_DECODER:
+ if (audio) {
+ audio->flush();
+ }
+ LOG_DEBUG_PLAYER_NC("Finished flushing audio decoder");
+ _flush_state = FlushState::FILL;
+ break;
+ case FlushState::FILL:
+ if (flush_fill() == FlushResult::DONE) {
+ LOG_DEBUG_PLAYER_NC("Finished flushing fills");
+ return FlushResult::DONE;
+ }
+ break;
+ }
+
+ return FlushResult::AGAIN;
+}
+
+
+/** @return true if we have finished flushing the codecs */
+FFmpegDecoder::FlushResult
+FFmpegDecoder::flush_codecs()
+{
+ bool did_something = false;
+ if (video) {
+ if (decode_and_process_video_packet(nullptr)) {
+ did_something = true;
+ }
+ }
+
+ for (auto i: ffmpeg_content()->ffmpeg_audio_streams()) {
+ auto context = _codec_context[i->index(_format_context)];
+ int r = avcodec_send_packet (context, nullptr);
+ if (r < 0 && r != AVERROR_EOF) {
+ /* EOF can happen if we've already sent a flush packet */
+ throw DecodeError (N_("avcodec_send_packet"), N_("FFmpegDecoder::flush"), r);
+ }
+ r = avcodec_receive_frame (context, audio_frame(i));
+ if (r >= 0) {
+ process_audio_frame (i);
+ did_something = true;
+ }
+ }
+
+ return did_something ? FlushResult::AGAIN : FlushResult::DONE;
+}