]> git.sesse.net Git - ffmpeg/blobdiff - ffplay.c
libopenjpegdec: always check image because decoding may still fail
[ffmpeg] / ffplay.c
index 749cfc7b9127fb46e9ccfdf2a2e3fcffbf284d76..00be13de43d899a470319617111e67ee4573b700 100644 (file)
--- a/ffplay.c
+++ b/ffplay.c
@@ -64,7 +64,6 @@ const char program_name[] = "ffplay";
 const int program_birth_year = 2003;
 
 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
-#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
 #define MIN_FRAMES 5
 
 /* SDL audio buffer size, in samples. Should be small to have precise
@@ -133,6 +132,7 @@ typedef struct VideoState {
     AVInputFormat *iformat;
     int no_background;
     int abort_request;
+    int force_refresh;
     int paused;
     int last_paused;
     int seek_req;
@@ -265,7 +265,6 @@ static int idct = FF_IDCT_AUTO;
 static enum AVDiscard skip_frame       = AVDISCARD_DEFAULT;
 static enum AVDiscard skip_idct        = AVDISCARD_DEFAULT;
 static enum AVDiscard skip_loop_filter = AVDISCARD_DEFAULT;
-static int error_recognition = FF_ER_CAREFUL;
 static int error_concealment = 3;
 static int decoder_reorder_pts = -1;
 static int autoexit;
@@ -994,7 +993,7 @@ static int refresh_thread(void *opaque)
         SDL_Event event;
         event.type = FF_REFRESH_EVENT;
         event.user.data1 = opaque;
-        if (!is->refresh) {
+        if (!is->refresh && (!is->paused || is->force_refresh)) {
             is->refresh = 1;
             SDL_PushEvent(&event);
         }
@@ -1157,6 +1156,9 @@ retry:
                 goto retry;
             }
 
+            if (is->paused)
+                goto display;
+
             /* compute nominal last_duration */
             last_duration = vp->pts - is->frame_last_pts;
             if (last_duration > 0 && last_duration < 10.0) {
@@ -1235,11 +1237,13 @@ retry:
                 }
             }
 
+display:
             /* display picture */
             if (!display_disable)
                 video_display(is);
 
-            pictq_next_picture(is);
+            if (!is->paused)
+                pictq_next_picture(is);
         }
     } else if (is->audio_st) {
         /* draw the next audio frame */
@@ -1251,6 +1255,7 @@ retry:
         if (!display_disable)
             video_display(is);
     }
+    is->force_refresh = 0;
     if (show_status) {
         static int64_t last_time;
         int64_t cur_time;
@@ -1546,7 +1551,7 @@ static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
     AVFilterContext *ctx = codec->opaque;
     AVFilterBufferRef  *ref;
     int perms = AV_PERM_WRITE;
-    int i, w, h, stride[4];
+    int i, w, h, stride[AV_NUM_DATA_POINTERS];
     unsigned edge;
     int pixel_size;
 
@@ -1565,7 +1570,7 @@ static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
     w = codec->width;
     h = codec->height;
 
-    if(av_image_check_size(w, h, 0, codec))
+    if(av_image_check_size(w, h, 0, codec) || codec->pix_fmt<0)
         return -1;
 
     avcodec_align_dimensions2(codec, &w, &h, stride);
@@ -1674,7 +1679,7 @@ static int input_request_frame(AVFilterLink *link)
     } else {
         picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
         av_image_copy(picref->data, picref->linesize,
-                      priv->frame->data, priv->frame->linesize,
+                      (const uint8_t **)(void **)priv->frame->data, priv->frame->linesize,
                       picref->format, link->w, link->h);
     }
     av_free_packet(&pkt);
@@ -1746,6 +1751,7 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
     if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
                                             NULL, is, graph)) < 0)
         return ret;
+
 #if FF_API_OLD_VSINK_API
     ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out",
                                        NULL, pix_fmts, graph);
@@ -2145,8 +2151,10 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
         if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
             return -1;
 
-        if (pkt->data == flush_pkt.data)
+        if (pkt->data == flush_pkt.data) {
             avcodec_flush_buffers(dec);
+            flush_complete = 0;
+        }
 
         *pkt_temp = *pkt;
 
@@ -2236,7 +2244,6 @@ static int stream_component_open(VideoState *is, int stream_index)
     avctx->skip_frame        = skip_frame;
     avctx->skip_idct         = skip_idct;
     avctx->skip_loop_filter  = skip_loop_filter;
-    avctx->error_recognition = error_recognition;
     avctx->error_concealment = error_concealment;
 
     if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
@@ -2245,6 +2252,7 @@ static int stream_component_open(VideoState *is, int stream_index)
         avctx->flags |= CODEC_FLAG_EMU_EDGE;
 
     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
+        memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
         env = SDL_getenv("SDL_AUDIO_CHANNELS");
         if (env)
             wanted_channel_layout = av_get_default_channel_layout(SDL_atoi(env));
@@ -2266,6 +2274,8 @@ static int stream_component_open(VideoState *is, int stream_index)
         }
     }
 
+    if (!av_dict_get(opts, "threads", NULL, 0))
+        av_dict_set(&opts, "threads", "auto", 0);
     if (!codec ||
         avcodec_open2(avctx, codec, &opts) < 0)
         return -1;
@@ -2601,7 +2611,7 @@ static int read_thread(void *arg)
 
         /* if the queue are full, no need to read more */
         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
-            || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream < 0)
+            || (   (is->audioq   .nb_packets > MIN_FRAMES || is->audio_stream < 0)
                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream < 0)
                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0))) {
             /* wait 10 ms */
@@ -2769,7 +2779,7 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
 
 static void toggle_full_screen(VideoState *is)
 {
-    int i;
+    av_unused int i;
     is_full_screen = !is_full_screen;
 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
     /* OS X needs to reallocate the SDL overlays */
@@ -2826,6 +2836,7 @@ static void event_loop(VideoState *cur_stream)
                 break;
             case SDLK_f:
                 toggle_full_screen(cur_stream);
+                cur_stream->force_refresh = 1;
                 break;
             case SDLK_p:
             case SDLK_SPACE:
@@ -2845,6 +2856,7 @@ static void event_loop(VideoState *cur_stream)
                 break;
             case SDLK_w:
                 toggle_audio_display(cur_stream);
+                cur_stream->force_refresh = 1;
                 break;
             case SDLK_PAGEUP:
                 incr = 600.0;
@@ -2887,6 +2899,9 @@ static void event_loop(VideoState *cur_stream)
                 break;
             }
             break;
+        case SDL_VIDEOEXPOSE:
+            cur_stream->force_refresh = 1;
+            break;
         case SDL_MOUSEBUTTONDOWN:
             if (exit_on_mousedown) {
                 do_exit(cur_stream);
@@ -2929,6 +2944,7 @@ static void event_loop(VideoState *cur_stream)
                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
                 screen_width  = cur_stream->width  = event.resize.w;
                 screen_height = cur_stream->height = event.resize.h;
+                cur_stream->force_refresh = 1;
             break;
         case SDL_QUIT:
         case FF_QUIT_EVENT:
@@ -3069,7 +3085,6 @@ static const OptionDef options[] = {
     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_frame }, "", "" },
     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_idct }, "", "" },
     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&idct }, "set idct algo",  "algo" },
-    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&error_recognition }, "set error detection threshold (0-4)",  "threshold" },
     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&error_concealment }, "set error concealment options",  "bit_mask" },
     { "sync", HAS_ARG | OPT_EXPERT, { (void*)opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
     { "autoexit", OPT_BOOL | OPT_EXPERT, { (void*)&autoexit }, "exit at the end", "" },
@@ -3215,7 +3230,7 @@ int main(int argc, char **argv)
     }
 
     av_init_packet(&flush_pkt);
-    flush_pkt.data = "FLUSH";
+    flush_pkt.data = (char *)(intptr_t)"FLUSH";
 
     is = stream_open(input_filename, file_iformat);
     if (!is) {