From 640b02ed04a36467cf8fc28eee139678c04fbea2 Mon Sep 17 00:00:00 2001
From: Marton Balint <cus@passwd.hu>
Date: Tue, 16 Jul 2013 03:04:22 +0200
Subject: [PATCH] ffplay: ensure we got the last frame from the decoder before
 exiting or looping

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 ffplay.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/ffplay.c b/ffplay.c
index d462eee..ea0ebdc 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -177,6 +177,8 @@ typedef struct VideoState {
     int read_pause_return;
     AVFormatContext *ic;
     int realtime;
+    int audio_finished;
+    int video_finished;
 
     Clock audclk;
     Clock vidclk;
@@ -1671,6 +1673,9 @@ static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *s
     if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
         return 0;
 
+    if (!got_picture && !pkt->data)
+        is->video_finished = *serial;
+
     if (got_picture) {
         int ret = 1;
         double dpts = NAN;
@@ -2166,6 +2171,8 @@ static int audio_decode_frame(VideoState *is)
                 pkt_temp->size -= len1;
                 if (pkt_temp->data && pkt_temp->size <= 0 || !pkt_temp->data && !got_frame)
                     pkt_temp->stream_index = -1;
+                if (!pkt_temp->data && !got_frame)
+                    is->audio_finished = is->audio_pkt_temp_serial;
 
                 if (!got_frame)
                     continue;
@@ -2895,6 +2902,15 @@ static int read_thread(void *arg)
             SDL_UnlockMutex(wait_mutex);
             continue;
         }
+        if ((!is->audio_st || is->audio_finished == is->audioq.serial) &&
+            (!is->video_st || is->video_finished == is->videoq.serial)) {
+            if (loop != 1 && (!loop || --loop)) {
+                stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
+            } else if (autoexit) {
+                ret = AVERROR_EOF;
+                goto fail;
+            }
+        }
         if (eof) {
             if (is->video_stream >= 0) {
                 av_init_packet(pkt);
@@ -2911,14 +2927,6 @@ static int read_thread(void *arg)
                 packet_queue_put(&is->audioq, pkt);
             }
             SDL_Delay(10);
-            if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
-                if (loop != 1 && (!loop || --loop)) {
-                    stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
-                } else if (autoexit) {
-                    ret = AVERROR_EOF;
-                    goto fail;
-                }
-            }
             eof=0;
             continue;
         }
-- 
1.8.1.4

