avplay: Do not try to allocate new frames when the player is closing

Message ID 20170425094350.355155DB29@aruru.libav.org
State New
Headers show

Commit Message

Janne Grunau April 25, 2017, 9:43 a.m.
Module: libav
Branch: master
Commit: 8c0cadd17e98547d84e82111550caca4fb40ff8d

Author:    Luca Barbato <lu_zero@gentoo.org>
Committer: Luca Barbato <lu_zero@gentoo.org>
Date:      Mon Apr 17 22:22:17 2017 +0000

avplay: Do not try to allocate new frames when the player is closing

The allocation event can trigger while the decoding thread is already
closing.

Bug-Id: 1052
CC: libav-stable@libav.org

---

 avtools/avplay.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

Patch

diff --git a/avtools/avplay.c b/avtools/avplay.c
index 26279e8..b6dbc52 100644
--- a/avtools/avplay.c
+++ b/avtools/avplay.c
@@ -213,6 +213,7 @@  typedef struct PlayerState {
 
     AVFilterContext *in_video_filter;   // the first filter in the video chain
     AVFilterContext *out_video_filter;  // the last filter in the video chain
+    SDL_mutex *video_filter_mutex;
 
     float skip_frames;
     float skip_frames_index;
@@ -1201,6 +1202,7 @@  static void player_close(PlayerState *is)
             vp->bmp = NULL;
         }
     }
+    SDL_DestroyMutex(is->video_filter_mutex);
     SDL_DestroyMutex(is->pictq_mutex);
     SDL_DestroyCond(is->pictq_cond);
     SDL_DestroyMutex(is->subpq_mutex);
@@ -1617,6 +1619,9 @@  static int video_thread(void *arg)
                 stream_pause(player);
     }
  the_end:
+    SDL_LockMutex(is->video_filter_mutex);
+    is->out_video_filter = NULL;
+    SDL_UnlockMutex(is->video_filter_mutex);
     av_freep(&vfilters);
     avfilter_graph_free(&graph);
     av_packet_unref(&pkt);
@@ -2552,6 +2557,8 @@  static int stream_open(PlayerState *is,
         return ret;
     }
 
+    is->video_filter_mutex = SDL_CreateMutex();
+
     /* start video display */
     is->pictq_mutex = SDL_CreateMutex();
     is->pictq_cond  = SDL_CreateCond();
@@ -2827,8 +2834,12 @@  static void event_loop(void)
             do_exit();
             break;
         case FF_ALLOC_EVENT:
-            video_open(event.user.data1);
-            alloc_picture(event.user.data1);
+            SDL_LockMutex(player->video_filter_mutex);
+            if (player->out_video_filter) {
+                video_open(event.user.data1);
+                alloc_picture(event.user.data1);
+            }
+            SDL_UnlockMutex(player->video_filter_mutex);
             break;
         case FF_REFRESH_EVENT:
             video_refresh_timer(event.user.data1);