]> git.sesse.net Git - ffmpeg/blob - ffplay.c
doc: document -opencl_options option in ff* tools manuals
[ffmpeg] / ffplay.c
1 /*
2  * Copyright (c) 2003 Fabrice Bellard
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * simple media player based on the FFmpeg libraries
24  */
25
26 #include "config.h"
27 #include <inttypes.h>
28 #include <math.h>
29 #include <limits.h>
30 #include <signal.h>
31 #include "libavutil/avstring.h"
32 #include "libavutil/colorspace.h"
33 #include "libavutil/mathematics.h"
34 #include "libavutil/pixdesc.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/dict.h"
37 #include "libavutil/parseutils.h"
38 #include "libavutil/samplefmt.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/time.h"
41 #include "libavformat/avformat.h"
42 #include "libavdevice/avdevice.h"
43 #include "libswscale/swscale.h"
44 #include "libavutil/opt.h"
45 #include "libavcodec/avfft.h"
46 #include "libswresample/swresample.h"
47
48 #if CONFIG_AVFILTER
49 # include "libavfilter/avcodec.h"
50 # include "libavfilter/avfilter.h"
51 # include "libavfilter/buffersink.h"
52 # include "libavfilter/buffersrc.h"
53 #endif
54
55 #include <SDL.h>
56 #include <SDL_thread.h>
57
58 #include "cmdutils.h"
59
60 #include <assert.h>
61
62 const char program_name[] = "ffplay";
63 const int program_birth_year = 2003;
64
65 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
66 #define MIN_FRAMES 5
67
68 /* SDL audio buffer size, in samples. Should be small to have precise
69    A/V sync as SDL does not have hardware buffer fullness info. */
70 #define SDL_AUDIO_BUFFER_SIZE 1024
71
72 /* no AV sync correction is done if below the AV sync threshold */
73 #define AV_SYNC_THRESHOLD 0.01
74 /* no AV correction is done if too big error */
75 #define AV_NOSYNC_THRESHOLD 10.0
76
77 /* maximum audio speed change to get correct sync */
78 #define SAMPLE_CORRECTION_PERCENT_MAX 10
79
80 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
81 #define EXTERNAL_CLOCK_SPEED_MIN  0.900
82 #define EXTERNAL_CLOCK_SPEED_MAX  1.010
83 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
84
85 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
86 #define AUDIO_DIFF_AVG_NB   20
87
88 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
89 #define REFRESH_RATE 0.01
90
91 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
92 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
93 #define SAMPLE_ARRAY_SIZE (8 * 65536)
94
95 #define CURSOR_HIDE_DELAY 1000000
96
97 static int64_t sws_flags = SWS_BICUBIC;
98
99 typedef struct MyAVPacketList {
100     AVPacket pkt;
101     struct MyAVPacketList *next;
102     int serial;
103 } MyAVPacketList;
104
105 typedef struct PacketQueue {
106     MyAVPacketList *first_pkt, *last_pkt;
107     int nb_packets;
108     int size;
109     int abort_request;
110     int serial;
111     SDL_mutex *mutex;
112     SDL_cond *cond;
113 } PacketQueue;
114
115 #define VIDEO_PICTURE_QUEUE_SIZE 4
116 #define SUBPICTURE_QUEUE_SIZE 4
117
118 typedef struct VideoPicture {
119     double pts;             // presentation timestamp for this picture
120     int64_t pos;            // byte position in file
121     SDL_Overlay *bmp;
122     int width, height; /* source height & width */
123     int allocated;
124     int reallocate;
125     int serial;
126
127     AVRational sar;
128 } VideoPicture;
129
130 typedef struct SubPicture {
131     double pts; /* presentation time stamp for this picture */
132     AVSubtitle sub;
133 } SubPicture;
134
135 typedef struct AudioParams {
136     int freq;
137     int channels;
138     int64_t channel_layout;
139     enum AVSampleFormat fmt;
140 } AudioParams;
141
142 enum {
143     AV_SYNC_AUDIO_MASTER, /* default choice */
144     AV_SYNC_VIDEO_MASTER,
145     AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
146 };
147
148 typedef struct VideoState {
149     SDL_Thread *read_tid;
150     SDL_Thread *video_tid;
151     AVInputFormat *iformat;
152     int no_background;
153     int abort_request;
154     int force_refresh;
155     int paused;
156     int last_paused;
157     int queue_attachments_req;
158     int seek_req;
159     int seek_flags;
160     int64_t seek_pos;
161     int64_t seek_rel;
162     int read_pause_return;
163     AVFormatContext *ic;
164     int realtime;
165
166     int audio_stream;
167
168     int av_sync_type;
169     double external_clock;                   ///< external clock base
170     double external_clock_drift;             ///< external clock base - time (av_gettime) at which we updated external_clock
171     int64_t external_clock_time;             ///< last reference time
172     double external_clock_speed;             ///< speed of the external clock
173
174     double audio_clock;
175     int audio_clock_serial;
176     double audio_diff_cum; /* used for AV difference average computation */
177     double audio_diff_avg_coef;
178     double audio_diff_threshold;
179     int audio_diff_avg_count;
180     AVStream *audio_st;
181     PacketQueue audioq;
182     int audio_hw_buf_size;
183     uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
184     uint8_t *audio_buf;
185     uint8_t *audio_buf1;
186     unsigned int audio_buf_size; /* in bytes */
187     unsigned int audio_buf1_size;
188     int audio_buf_index; /* in bytes */
189     int audio_write_buf_size;
190     int audio_buf_frames_pending;
191     AVPacket audio_pkt_temp;
192     AVPacket audio_pkt;
193     int audio_pkt_temp_serial;
194     int audio_last_serial;
195     struct AudioParams audio_src;
196 #if CONFIG_AVFILTER
197     struct AudioParams audio_filter_src;
198 #endif
199     struct AudioParams audio_tgt;
200     struct SwrContext *swr_ctx;
201     double audio_current_pts;
202     double audio_current_pts_drift;
203     int frame_drops_early;
204     int frame_drops_late;
205     AVFrame *frame;
206
207     enum ShowMode {
208         SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
209     } show_mode;
210     int16_t sample_array[SAMPLE_ARRAY_SIZE];
211     int sample_array_index;
212     int last_i_start;
213     RDFTContext *rdft;
214     int rdft_bits;
215     FFTSample *rdft_data;
216     int xpos;
217     double last_vis_time;
218
219     SDL_Thread *subtitle_tid;
220     int subtitle_stream;
221     int subtitle_stream_changed;
222     AVStream *subtitle_st;
223     PacketQueue subtitleq;
224     SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
225     int subpq_size, subpq_rindex, subpq_windex;
226     SDL_mutex *subpq_mutex;
227     SDL_cond *subpq_cond;
228
229     double frame_timer;
230     double frame_last_pts;
231     double frame_last_duration;
232     double frame_last_dropped_pts;
233     double frame_last_returned_time;
234     double frame_last_filter_delay;
235     int64_t frame_last_dropped_pos;
236     int frame_last_dropped_serial;
237     int video_stream;
238     AVStream *video_st;
239     PacketQueue videoq;
240     double video_current_pts;       // current displayed pts
241     double video_current_pts_drift; // video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
242     int64_t video_current_pos;      // current displayed file pos
243     double max_frame_duration;      // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
244     int video_clock_serial;
245     VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
246     int pictq_size, pictq_rindex, pictq_windex;
247     SDL_mutex *pictq_mutex;
248     SDL_cond *pictq_cond;
249 #if !CONFIG_AVFILTER
250     struct SwsContext *img_convert_ctx;
251 #endif
252     SDL_Rect last_display_rect;
253
254     char filename[1024];
255     int width, height, xleft, ytop;
256     int step;
257
258 #if CONFIG_AVFILTER
259     AVFilterContext *in_video_filter;   // the first filter in the video chain
260     AVFilterContext *out_video_filter;  // the last filter in the video chain
261     AVFilterContext *in_audio_filter;   // the first filter in the audio chain
262     AVFilterContext *out_audio_filter;  // the last filter in the audio chain
263     AVFilterGraph *agraph;              // audio filter graph
264 #endif
265
266     int last_video_stream, last_audio_stream, last_subtitle_stream;
267
268     SDL_cond *continue_read_thread;
269 } VideoState;
270
271 /* options specified by the user */
272 static AVInputFormat *file_iformat;
273 static const char *input_filename;
274 static const char *window_title;
275 static int fs_screen_width;
276 static int fs_screen_height;
277 static int default_width  = 640;
278 static int default_height = 480;
279 static int screen_width  = 0;
280 static int screen_height = 0;
281 static int audio_disable;
282 static int video_disable;
283 static int subtitle_disable;
284 static int wanted_stream[AVMEDIA_TYPE_NB] = {
285     [AVMEDIA_TYPE_AUDIO]    = -1,
286     [AVMEDIA_TYPE_VIDEO]    = -1,
287     [AVMEDIA_TYPE_SUBTITLE] = -1,
288 };
289 static int seek_by_bytes = -1;
290 static int display_disable;
291 static int show_status = 1;
292 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
293 static int64_t start_time = AV_NOPTS_VALUE;
294 static int64_t duration = AV_NOPTS_VALUE;
295 static int workaround_bugs = 1;
296 static int fast = 0;
297 static int genpts = 0;
298 static int lowres = 0;
299 static int idct = FF_IDCT_AUTO;
300 static int error_concealment = 3;
301 static int decoder_reorder_pts = -1;
302 static int autoexit;
303 static int exit_on_keydown;
304 static int exit_on_mousedown;
305 static int loop = 1;
306 static int framedrop = -1;
307 static int infinite_buffer = -1;
308 static enum ShowMode show_mode = SHOW_MODE_NONE;
309 static const char *audio_codec_name;
310 static const char *subtitle_codec_name;
311 static const char *video_codec_name;
312 double rdftspeed = 0.02;
313 static int64_t cursor_last_shown;
314 static int cursor_hidden = 0;
315 #if CONFIG_AVFILTER
316 static char *vfilters = NULL;
317 static char *afilters = NULL;
318 #endif
319
320 /* current context */
321 static int is_full_screen;
322 static int64_t audio_callback_time;
323
324 static AVPacket flush_pkt;
325
326 #define FF_ALLOC_EVENT   (SDL_USEREVENT)
327 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
328
329 static SDL_Surface *screen;
330
331 static inline
332 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
333                    enum AVSampleFormat fmt2, int64_t channel_count2)
334 {
335     /* If channel count == 1, planar and non-planar formats are the same */
336     if (channel_count1 == 1 && channel_count2 == 1)
337         return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
338     else
339         return channel_count1 != channel_count2 || fmt1 != fmt2;
340 }
341
342 static inline
343 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
344 {
345     if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
346         return channel_layout;
347     else
348         return 0;
349 }
350
351 static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
352
353 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
354 {
355     MyAVPacketList *pkt1;
356
357     if (q->abort_request)
358        return -1;
359
360     pkt1 = av_malloc(sizeof(MyAVPacketList));
361     if (!pkt1)
362         return -1;
363     pkt1->pkt = *pkt;
364     pkt1->next = NULL;
365     if (pkt == &flush_pkt)
366         q->serial++;
367     pkt1->serial = q->serial;
368
369     if (!q->last_pkt)
370         q->first_pkt = pkt1;
371     else
372         q->last_pkt->next = pkt1;
373     q->last_pkt = pkt1;
374     q->nb_packets++;
375     q->size += pkt1->pkt.size + sizeof(*pkt1);
376     /* XXX: should duplicate packet data in DV case */
377     SDL_CondSignal(q->cond);
378     return 0;
379 }
380
381 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
382 {
383     int ret;
384
385     /* duplicate the packet */
386     if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
387         return -1;
388
389     SDL_LockMutex(q->mutex);
390     ret = packet_queue_put_private(q, pkt);
391     SDL_UnlockMutex(q->mutex);
392
393     if (pkt != &flush_pkt && ret < 0)
394         av_free_packet(pkt);
395
396     return ret;
397 }
398
399 /* packet queue handling */
400 static void packet_queue_init(PacketQueue *q)
401 {
402     memset(q, 0, sizeof(PacketQueue));
403     q->mutex = SDL_CreateMutex();
404     q->cond = SDL_CreateCond();
405     q->abort_request = 1;
406 }
407
408 static void packet_queue_flush(PacketQueue *q)
409 {
410     MyAVPacketList *pkt, *pkt1;
411
412     SDL_LockMutex(q->mutex);
413     for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
414         pkt1 = pkt->next;
415         av_free_packet(&pkt->pkt);
416         av_freep(&pkt);
417     }
418     q->last_pkt = NULL;
419     q->first_pkt = NULL;
420     q->nb_packets = 0;
421     q->size = 0;
422     SDL_UnlockMutex(q->mutex);
423 }
424
425 static void packet_queue_destroy(PacketQueue *q)
426 {
427     packet_queue_flush(q);
428     SDL_DestroyMutex(q->mutex);
429     SDL_DestroyCond(q->cond);
430 }
431
432 static void packet_queue_abort(PacketQueue *q)
433 {
434     SDL_LockMutex(q->mutex);
435
436     q->abort_request = 1;
437
438     SDL_CondSignal(q->cond);
439
440     SDL_UnlockMutex(q->mutex);
441 }
442
443 static void packet_queue_start(PacketQueue *q)
444 {
445     SDL_LockMutex(q->mutex);
446     q->abort_request = 0;
447     packet_queue_put_private(q, &flush_pkt);
448     SDL_UnlockMutex(q->mutex);
449 }
450
451 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
452 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
453 {
454     MyAVPacketList *pkt1;
455     int ret;
456
457     SDL_LockMutex(q->mutex);
458
459     for (;;) {
460         if (q->abort_request) {
461             ret = -1;
462             break;
463         }
464
465         pkt1 = q->first_pkt;
466         if (pkt1) {
467             q->first_pkt = pkt1->next;
468             if (!q->first_pkt)
469                 q->last_pkt = NULL;
470             q->nb_packets--;
471             q->size -= pkt1->pkt.size + sizeof(*pkt1);
472             *pkt = pkt1->pkt;
473             if (serial)
474                 *serial = pkt1->serial;
475             av_free(pkt1);
476             ret = 1;
477             break;
478         } else if (!block) {
479             ret = 0;
480             break;
481         } else {
482             SDL_CondWait(q->cond, q->mutex);
483         }
484     }
485     SDL_UnlockMutex(q->mutex);
486     return ret;
487 }
488
489 static inline void fill_rectangle(SDL_Surface *screen,
490                                   int x, int y, int w, int h, int color, int update)
491 {
492     SDL_Rect rect;
493     rect.x = x;
494     rect.y = y;
495     rect.w = w;
496     rect.h = h;
497     SDL_FillRect(screen, &rect, color);
498     if (update && w > 0 && h > 0)
499         SDL_UpdateRect(screen, x, y, w, h);
500 }
501
502 /* draw only the border of a rectangle */
503 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
504 {
505     int w1, w2, h1, h2;
506
507     /* fill the background */
508     w1 = x;
509     if (w1 < 0)
510         w1 = 0;
511     w2 = width - (x + w);
512     if (w2 < 0)
513         w2 = 0;
514     h1 = y;
515     if (h1 < 0)
516         h1 = 0;
517     h2 = height - (y + h);
518     if (h2 < 0)
519         h2 = 0;
520     fill_rectangle(screen,
521                    xleft, ytop,
522                    w1, height,
523                    color, update);
524     fill_rectangle(screen,
525                    xleft + width - w2, ytop,
526                    w2, height,
527                    color, update);
528     fill_rectangle(screen,
529                    xleft + w1, ytop,
530                    width - w1 - w2, h1,
531                    color, update);
532     fill_rectangle(screen,
533                    xleft + w1, ytop + height - h2,
534                    width - w1 - w2, h2,
535                    color, update);
536 }
537
538 #define ALPHA_BLEND(a, oldp, newp, s)\
539 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
540
541 #define RGBA_IN(r, g, b, a, s)\
542 {\
543     unsigned int v = ((const uint32_t *)(s))[0];\
544     a = (v >> 24) & 0xff;\
545     r = (v >> 16) & 0xff;\
546     g = (v >> 8) & 0xff;\
547     b = v & 0xff;\
548 }
549
550 #define YUVA_IN(y, u, v, a, s, pal)\
551 {\
552     unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
553     a = (val >> 24) & 0xff;\
554     y = (val >> 16) & 0xff;\
555     u = (val >> 8) & 0xff;\
556     v = val & 0xff;\
557 }
558
559 #define YUVA_OUT(d, y, u, v, a)\
560 {\
561     ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
562 }
563
564
565 #define BPP 1
566
567 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
568 {
569     int wrap, wrap3, width2, skip2;
570     int y, u, v, a, u1, v1, a1, w, h;
571     uint8_t *lum, *cb, *cr;
572     const uint8_t *p;
573     const uint32_t *pal;
574     int dstx, dsty, dstw, dsth;
575
576     dstw = av_clip(rect->w, 0, imgw);
577     dsth = av_clip(rect->h, 0, imgh);
578     dstx = av_clip(rect->x, 0, imgw - dstw);
579     dsty = av_clip(rect->y, 0, imgh - dsth);
580     lum = dst->data[0] + dsty * dst->linesize[0];
581     cb  = dst->data[1] + (dsty >> 1) * dst->linesize[1];
582     cr  = dst->data[2] + (dsty >> 1) * dst->linesize[2];
583
584     width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
585     skip2 = dstx >> 1;
586     wrap = dst->linesize[0];
587     wrap3 = rect->pict.linesize[0];
588     p = rect->pict.data[0];
589     pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
590
591     if (dsty & 1) {
592         lum += dstx;
593         cb += skip2;
594         cr += skip2;
595
596         if (dstx & 1) {
597             YUVA_IN(y, u, v, a, p, pal);
598             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
599             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
600             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
601             cb++;
602             cr++;
603             lum++;
604             p += BPP;
605         }
606         for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
607             YUVA_IN(y, u, v, a, p, pal);
608             u1 = u;
609             v1 = v;
610             a1 = a;
611             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
612
613             YUVA_IN(y, u, v, a, p + BPP, pal);
614             u1 += u;
615             v1 += v;
616             a1 += a;
617             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
618             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
619             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
620             cb++;
621             cr++;
622             p += 2 * BPP;
623             lum += 2;
624         }
625         if (w) {
626             YUVA_IN(y, u, v, a, p, pal);
627             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
628             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
629             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
630             p++;
631             lum++;
632         }
633         p += wrap3 - dstw * BPP;
634         lum += wrap - dstw - dstx;
635         cb += dst->linesize[1] - width2 - skip2;
636         cr += dst->linesize[2] - width2 - skip2;
637     }
638     for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
639         lum += dstx;
640         cb += skip2;
641         cr += skip2;
642
643         if (dstx & 1) {
644             YUVA_IN(y, u, v, a, p, pal);
645             u1 = u;
646             v1 = v;
647             a1 = a;
648             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
649             p += wrap3;
650             lum += wrap;
651             YUVA_IN(y, u, v, a, p, pal);
652             u1 += u;
653             v1 += v;
654             a1 += a;
655             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
656             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
657             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
658             cb++;
659             cr++;
660             p += -wrap3 + BPP;
661             lum += -wrap + 1;
662         }
663         for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
664             YUVA_IN(y, u, v, a, p, pal);
665             u1 = u;
666             v1 = v;
667             a1 = a;
668             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
669
670             YUVA_IN(y, u, v, a, p + BPP, pal);
671             u1 += u;
672             v1 += v;
673             a1 += a;
674             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
675             p += wrap3;
676             lum += wrap;
677
678             YUVA_IN(y, u, v, a, p, pal);
679             u1 += u;
680             v1 += v;
681             a1 += a;
682             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
683
684             YUVA_IN(y, u, v, a, p + BPP, pal);
685             u1 += u;
686             v1 += v;
687             a1 += a;
688             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
689
690             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
691             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
692
693             cb++;
694             cr++;
695             p += -wrap3 + 2 * BPP;
696             lum += -wrap + 2;
697         }
698         if (w) {
699             YUVA_IN(y, u, v, a, p, pal);
700             u1 = u;
701             v1 = v;
702             a1 = a;
703             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
704             p += wrap3;
705             lum += wrap;
706             YUVA_IN(y, u, v, a, p, pal);
707             u1 += u;
708             v1 += v;
709             a1 += a;
710             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
711             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
712             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
713             cb++;
714             cr++;
715             p += -wrap3 + BPP;
716             lum += -wrap + 1;
717         }
718         p += wrap3 + (wrap3 - dstw * BPP);
719         lum += wrap + (wrap - dstw - dstx);
720         cb += dst->linesize[1] - width2 - skip2;
721         cr += dst->linesize[2] - width2 - skip2;
722     }
723     /* handle odd height */
724     if (h) {
725         lum += dstx;
726         cb += skip2;
727         cr += skip2;
728
729         if (dstx & 1) {
730             YUVA_IN(y, u, v, a, p, pal);
731             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
732             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
733             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
734             cb++;
735             cr++;
736             lum++;
737             p += BPP;
738         }
739         for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
740             YUVA_IN(y, u, v, a, p, pal);
741             u1 = u;
742             v1 = v;
743             a1 = a;
744             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
745
746             YUVA_IN(y, u, v, a, p + BPP, pal);
747             u1 += u;
748             v1 += v;
749             a1 += a;
750             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
751             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
752             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
753             cb++;
754             cr++;
755             p += 2 * BPP;
756             lum += 2;
757         }
758         if (w) {
759             YUVA_IN(y, u, v, a, p, pal);
760             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
761             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
762             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
763         }
764     }
765 }
766
767 static void free_subpicture(SubPicture *sp)
768 {
769     avsubtitle_free(&sp->sub);
770 }
771
772 static void calculate_display_rect(SDL_Rect *rect, int scr_xleft, int scr_ytop, int scr_width, int scr_height, VideoPicture *vp)
773 {
774     float aspect_ratio;
775     int width, height, x, y;
776
777     if (vp->sar.num == 0)
778         aspect_ratio = 0;
779     else
780         aspect_ratio = av_q2d(vp->sar);
781
782     if (aspect_ratio <= 0.0)
783         aspect_ratio = 1.0;
784     aspect_ratio *= (float)vp->width / (float)vp->height;
785
786     /* XXX: we suppose the screen has a 1.0 pixel ratio */
787     height = scr_height;
788     width = ((int)rint(height * aspect_ratio)) & ~1;
789     if (width > scr_width) {
790         width = scr_width;
791         height = ((int)rint(width / aspect_ratio)) & ~1;
792     }
793     x = (scr_width - width) / 2;
794     y = (scr_height - height) / 2;
795     rect->x = scr_xleft + x;
796     rect->y = scr_ytop  + y;
797     rect->w = FFMAX(width,  1);
798     rect->h = FFMAX(height, 1);
799 }
800
801 static void video_image_display(VideoState *is)
802 {
803     VideoPicture *vp;
804     SubPicture *sp;
805     AVPicture pict;
806     SDL_Rect rect;
807     int i;
808
809     vp = &is->pictq[is->pictq_rindex];
810     if (vp->bmp) {
811         if (is->subtitle_st) {
812             if (is->subpq_size > 0) {
813                 sp = &is->subpq[is->subpq_rindex];
814
815                 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
816                     SDL_LockYUVOverlay (vp->bmp);
817
818                     pict.data[0] = vp->bmp->pixels[0];
819                     pict.data[1] = vp->bmp->pixels[2];
820                     pict.data[2] = vp->bmp->pixels[1];
821
822                     pict.linesize[0] = vp->bmp->pitches[0];
823                     pict.linesize[1] = vp->bmp->pitches[2];
824                     pict.linesize[2] = vp->bmp->pitches[1];
825
826                     for (i = 0; i < sp->sub.num_rects; i++)
827                         blend_subrect(&pict, sp->sub.rects[i],
828                                       vp->bmp->w, vp->bmp->h);
829
830                     SDL_UnlockYUVOverlay (vp->bmp);
831                 }
832             }
833         }
834
835         calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp);
836
837         SDL_DisplayYUVOverlay(vp->bmp, &rect);
838
839         if (rect.x != is->last_display_rect.x || rect.y != is->last_display_rect.y || rect.w != is->last_display_rect.w || rect.h != is->last_display_rect.h || is->force_refresh) {
840             int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
841             fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
842             is->last_display_rect = rect;
843         }
844     }
845 }
846
847 static inline int compute_mod(int a, int b)
848 {
849     return a < 0 ? a%b + b : a%b;
850 }
851
852 static void video_audio_display(VideoState *s)
853 {
854     int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
855     int ch, channels, h, h2, bgcolor, fgcolor;
856     int64_t time_diff;
857     int rdft_bits, nb_freq;
858
859     for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
860         ;
861     nb_freq = 1 << (rdft_bits - 1);
862
863     /* compute display index : center on currently output samples */
864     channels = s->audio_tgt.channels;
865     nb_display_channels = channels;
866     if (!s->paused) {
867         int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
868         n = 2 * channels;
869         delay = s->audio_write_buf_size;
870         delay /= n;
871
872         /* to be more precise, we take into account the time spent since
873            the last buffer computation */
874         if (audio_callback_time) {
875             time_diff = av_gettime() - audio_callback_time;
876             delay -= (time_diff * s->audio_tgt.freq) / 1000000;
877         }
878
879         delay += 2 * data_used;
880         if (delay < data_used)
881             delay = data_used;
882
883         i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
884         if (s->show_mode == SHOW_MODE_WAVES) {
885             h = INT_MIN;
886             for (i = 0; i < 1000; i += channels) {
887                 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
888                 int a = s->sample_array[idx];
889                 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
890                 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
891                 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
892                 int score = a - d;
893                 if (h < score && (b ^ c) < 0) {
894                     h = score;
895                     i_start = idx;
896                 }
897             }
898         }
899
900         s->last_i_start = i_start;
901     } else {
902         i_start = s->last_i_start;
903     }
904
905     bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
906     if (s->show_mode == SHOW_MODE_WAVES) {
907         fill_rectangle(screen,
908                        s->xleft, s->ytop, s->width, s->height,
909                        bgcolor, 0);
910
911         fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
912
913         /* total height for one channel */
914         h = s->height / nb_display_channels;
915         /* graph height / 2 */
916         h2 = (h * 9) / 20;
917         for (ch = 0; ch < nb_display_channels; ch++) {
918             i = i_start + ch;
919             y1 = s->ytop + ch * h + (h / 2); /* position of center line */
920             for (x = 0; x < s->width; x++) {
921                 y = (s->sample_array[i] * h2) >> 15;
922                 if (y < 0) {
923                     y = -y;
924                     ys = y1 - y;
925                 } else {
926                     ys = y1;
927                 }
928                 fill_rectangle(screen,
929                                s->xleft + x, ys, 1, y,
930                                fgcolor, 0);
931                 i += channels;
932                 if (i >= SAMPLE_ARRAY_SIZE)
933                     i -= SAMPLE_ARRAY_SIZE;
934             }
935         }
936
937         fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
938
939         for (ch = 1; ch < nb_display_channels; ch++) {
940             y = s->ytop + ch * h;
941             fill_rectangle(screen,
942                            s->xleft, y, s->width, 1,
943                            fgcolor, 0);
944         }
945         SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
946     } else {
947         nb_display_channels= FFMIN(nb_display_channels, 2);
948         if (rdft_bits != s->rdft_bits) {
949             av_rdft_end(s->rdft);
950             av_free(s->rdft_data);
951             s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
952             s->rdft_bits = rdft_bits;
953             s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data));
954         }
955         {
956             FFTSample *data[2];
957             for (ch = 0; ch < nb_display_channels; ch++) {
958                 data[ch] = s->rdft_data + 2 * nb_freq * ch;
959                 i = i_start + ch;
960                 for (x = 0; x < 2 * nb_freq; x++) {
961                     double w = (x-nb_freq) * (1.0 / nb_freq);
962                     data[ch][x] = s->sample_array[i] * (1.0 - w * w);
963                     i += channels;
964                     if (i >= SAMPLE_ARRAY_SIZE)
965                         i -= SAMPLE_ARRAY_SIZE;
966                 }
967                 av_rdft_calc(s->rdft, data[ch]);
968             }
969             // least efficient way to do this, we should of course directly access it but its more than fast enough
970             for (y = 0; y < s->height; y++) {
971                 double w = 1 / sqrt(nb_freq);
972                 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
973                 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
974                        + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
975                 a = FFMIN(a, 255);
976                 b = FFMIN(b, 255);
977                 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
978
979                 fill_rectangle(screen,
980                             s->xpos, s->height-y, 1, 1,
981                             fgcolor, 0);
982             }
983         }
984         SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
985         if (!s->paused)
986             s->xpos++;
987         if (s->xpos >= s->width)
988             s->xpos= s->xleft;
989     }
990 }
991
992 static void stream_close(VideoState *is)
993 {
994     VideoPicture *vp;
995     int i;
996     /* XXX: use a special url_shutdown call to abort parse cleanly */
997     is->abort_request = 1;
998     SDL_WaitThread(is->read_tid, NULL);
999     packet_queue_destroy(&is->videoq);
1000     packet_queue_destroy(&is->audioq);
1001     packet_queue_destroy(&is->subtitleq);
1002
1003     /* free all pictures */
1004     for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
1005         vp = &is->pictq[i];
1006         if (vp->bmp) {
1007             SDL_FreeYUVOverlay(vp->bmp);
1008             vp->bmp = NULL;
1009         }
1010     }
1011     SDL_DestroyMutex(is->pictq_mutex);
1012     SDL_DestroyCond(is->pictq_cond);
1013     SDL_DestroyMutex(is->subpq_mutex);
1014     SDL_DestroyCond(is->subpq_cond);
1015     SDL_DestroyCond(is->continue_read_thread);
1016 #if !CONFIG_AVFILTER
1017     sws_freeContext(is->img_convert_ctx);
1018 #endif
1019     av_free(is);
1020 }
1021
1022 static void do_exit(VideoState *is)
1023 {
1024     if (is) {
1025         stream_close(is);
1026     }
1027     av_lockmgr_register(NULL);
1028     uninit_opts();
1029 #if CONFIG_AVFILTER
1030     av_freep(&vfilters);
1031 #endif
1032     avformat_network_deinit();
1033     if (show_status)
1034         printf("\n");
1035     SDL_Quit();
1036     av_log(NULL, AV_LOG_QUIET, "%s", "");
1037     exit(0);
1038 }
1039
1040 static void sigterm_handler(int sig)
1041 {
1042     exit(123);
1043 }
1044
1045 static int video_open(VideoState *is, int force_set_video_mode, VideoPicture *vp)
1046 {
1047     int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1048     int w,h;
1049     SDL_Rect rect;
1050
1051     if (is_full_screen) flags |= SDL_FULLSCREEN;
1052     else                flags |= SDL_RESIZABLE;
1053
1054     if (vp && vp->width) {
1055         calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
1056         default_width  = rect.w;
1057         default_height = rect.h;
1058     }
1059
1060     if (is_full_screen && fs_screen_width) {
1061         w = fs_screen_width;
1062         h = fs_screen_height;
1063     } else if (!is_full_screen && screen_width) {
1064         w = screen_width;
1065         h = screen_height;
1066     } else {
1067         w = default_width;
1068         h = default_height;
1069     }
1070     if (screen && is->width == screen->w && screen->w == w
1071        && is->height== screen->h && screen->h == h && !force_set_video_mode)
1072         return 0;
1073     screen = SDL_SetVideoMode(w, h, 0, flags);
1074     if (!screen) {
1075         fprintf(stderr, "SDL: could not set video mode - exiting\n");
1076         do_exit(is);
1077     }
1078     if (!window_title)
1079         window_title = input_filename;
1080     SDL_WM_SetCaption(window_title, window_title);
1081
1082     is->width  = screen->w;
1083     is->height = screen->h;
1084
1085     return 0;
1086 }
1087
1088 /* display the current picture, if any */
1089 static void video_display(VideoState *is)
1090 {
1091     if (!screen)
1092         video_open(is, 0, NULL);
1093     if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1094         video_audio_display(is);
1095     else if (is->video_st)
1096         video_image_display(is);
1097 }
1098
1099 /* get the current audio clock value */
1100 static double get_audio_clock(VideoState *is)
1101 {
1102     if (is->audio_clock_serial != is->audioq.serial)
1103         return NAN;
1104     if (is->paused) {
1105         return is->audio_current_pts;
1106     } else {
1107         return is->audio_current_pts_drift + av_gettime() / 1000000.0;
1108     }
1109 }
1110
1111 /* get the current video clock value */
1112 static double get_video_clock(VideoState *is)
1113 {
1114     if (is->video_clock_serial != is->videoq.serial)
1115         return NAN;
1116     if (is->paused) {
1117         return is->video_current_pts;
1118     } else {
1119         return is->video_current_pts_drift + av_gettime() / 1000000.0;
1120     }
1121 }
1122
1123 /* get the current external clock value */
1124 static double get_external_clock(VideoState *is)
1125 {
1126     if (is->paused) {
1127         return is->external_clock;
1128     } else {
1129         double time = av_gettime() / 1000000.0;
1130         return is->external_clock_drift + time - (time - is->external_clock_time / 1000000.0) * (1.0 - is->external_clock_speed);
1131     }
1132 }
1133
1134 static int get_master_sync_type(VideoState *is) {
1135     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1136         if (is->video_st)
1137             return AV_SYNC_VIDEO_MASTER;
1138         else
1139             return AV_SYNC_AUDIO_MASTER;
1140     } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1141         if (is->audio_st)
1142             return AV_SYNC_AUDIO_MASTER;
1143         else
1144             return AV_SYNC_EXTERNAL_CLOCK;
1145     } else {
1146         return AV_SYNC_EXTERNAL_CLOCK;
1147     }
1148 }
1149
1150 /* get the current master clock value */
1151 static double get_master_clock(VideoState *is)
1152 {
1153     double val;
1154
1155     switch (get_master_sync_type(is)) {
1156         case AV_SYNC_VIDEO_MASTER:
1157             val = get_video_clock(is);
1158             break;
1159         case AV_SYNC_AUDIO_MASTER:
1160             val = get_audio_clock(is);
1161             break;
1162         default:
1163             val = get_external_clock(is);
1164             break;
1165     }
1166     return val;
1167 }
1168
1169 static void update_external_clock_pts(VideoState *is, double pts)
1170 {
1171    is->external_clock_time = av_gettime();
1172    is->external_clock = pts;
1173    is->external_clock_drift = pts - is->external_clock_time / 1000000.0;
1174 }
1175
1176 static void check_external_clock_sync(VideoState *is, double pts) {
1177     double ext_clock = get_external_clock(is);
1178     if (isnan(ext_clock) || fabs(ext_clock - pts) > AV_NOSYNC_THRESHOLD) {
1179         update_external_clock_pts(is, pts);
1180     }
1181 }
1182
1183 static void update_external_clock_speed(VideoState *is, double speed) {
1184     update_external_clock_pts(is, get_external_clock(is));
1185     is->external_clock_speed = speed;
1186 }
1187
1188 static void check_external_clock_speed(VideoState *is) {
1189    if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1190        is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1191        update_external_clock_speed(is, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->external_clock_speed - EXTERNAL_CLOCK_SPEED_STEP));
1192    } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1193               (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1194        update_external_clock_speed(is, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->external_clock_speed + EXTERNAL_CLOCK_SPEED_STEP));
1195    } else {
1196        double speed = is->external_clock_speed;
1197        if (speed != 1.0)
1198            update_external_clock_speed(is, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1199    }
1200 }
1201
1202 /* seek in the stream */
1203 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1204 {
1205     if (!is->seek_req) {
1206         is->seek_pos = pos;
1207         is->seek_rel = rel;
1208         is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1209         if (seek_by_bytes)
1210             is->seek_flags |= AVSEEK_FLAG_BYTE;
1211         is->seek_req = 1;
1212         SDL_CondSignal(is->continue_read_thread);
1213     }
1214 }
1215
1216 /* pause or resume the video */
1217 static void stream_toggle_pause(VideoState *is)
1218 {
1219     if (is->paused) {
1220         is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
1221         if (is->read_pause_return != AVERROR(ENOSYS)) {
1222             is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1223         }
1224         is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1225     }
1226     update_external_clock_pts(is, get_external_clock(is));
1227     is->paused = !is->paused;
1228 }
1229
1230 static void toggle_pause(VideoState *is)
1231 {
1232     stream_toggle_pause(is);
1233     is->step = 0;
1234 }
1235
1236 static void step_to_next_frame(VideoState *is)
1237 {
1238     /* if the stream is paused unpause it, then step */
1239     if (is->paused)
1240         stream_toggle_pause(is);
1241     is->step = 1;
1242 }
1243
1244 static double compute_target_delay(double delay, VideoState *is)
1245 {
1246     double sync_threshold, diff;
1247
1248     /* update delay to follow master synchronisation source */
1249     if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1250         /* if video is slave, we try to correct big delays by
1251            duplicating or deleting a frame */
1252         diff = get_video_clock(is) - get_master_clock(is);
1253
1254         /* skip or repeat frame. We take into account the
1255            delay to compute the threshold. I still don't know
1256            if it is the best guess */
1257         sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1258         if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
1259             if (diff <= -sync_threshold)
1260                 delay = 0;
1261             else if (diff >= sync_threshold)
1262                 delay = 2 * delay;
1263         }
1264     }
1265
1266     av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1267             delay, -diff);
1268
1269     return delay;
1270 }
1271
1272 static void pictq_next_picture(VideoState *is) {
1273     /* update queue size and signal for next picture */
1274     if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1275         is->pictq_rindex = 0;
1276
1277     SDL_LockMutex(is->pictq_mutex);
1278     is->pictq_size--;
1279     SDL_CondSignal(is->pictq_cond);
1280     SDL_UnlockMutex(is->pictq_mutex);
1281 }
1282
1283 static int pictq_prev_picture(VideoState *is) {
1284     VideoPicture *prevvp;
1285     int ret = 0;
1286     /* update queue size and signal for the previous picture */
1287     prevvp = &is->pictq[(is->pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1) % VIDEO_PICTURE_QUEUE_SIZE];
1288     if (prevvp->allocated && prevvp->serial == is->videoq.serial) {
1289         SDL_LockMutex(is->pictq_mutex);
1290         if (is->pictq_size < VIDEO_PICTURE_QUEUE_SIZE - 1) {
1291             if (--is->pictq_rindex == -1)
1292                 is->pictq_rindex = VIDEO_PICTURE_QUEUE_SIZE - 1;
1293             is->pictq_size++;
1294             ret = 1;
1295         }
1296         SDL_CondSignal(is->pictq_cond);
1297         SDL_UnlockMutex(is->pictq_mutex);
1298     }
1299     return ret;
1300 }
1301
1302 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1303     double time = av_gettime() / 1000000.0;
1304     /* update current video pts */
1305     is->video_current_pts = pts;
1306     is->video_current_pts_drift = is->video_current_pts - time;
1307     is->video_current_pos = pos;
1308     is->frame_last_pts = pts;
1309     is->video_clock_serial = serial;
1310     if (is->videoq.serial == serial)
1311         check_external_clock_sync(is, is->video_current_pts);
1312 }
1313
1314 /* called to display each frame */
1315 static void video_refresh(void *opaque, double *remaining_time)
1316 {
1317     VideoState *is = opaque;
1318     VideoPicture *vp;
1319     double time;
1320
1321     SubPicture *sp, *sp2;
1322
1323     if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1324         check_external_clock_speed(is);
1325
1326     if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1327         time = av_gettime() / 1000000.0;
1328         if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1329             video_display(is);
1330             is->last_vis_time = time;
1331         }
1332         *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1333     }
1334
1335     if (is->video_st) {
1336         int redisplay = 0;
1337         if (is->force_refresh)
1338             redisplay = pictq_prev_picture(is);
1339 retry:
1340         if (is->pictq_size == 0) {
1341             SDL_LockMutex(is->pictq_mutex);
1342             if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
1343                 update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos, is->frame_last_dropped_serial);
1344                 is->frame_last_dropped_pts = AV_NOPTS_VALUE;
1345             }
1346             SDL_UnlockMutex(is->pictq_mutex);
1347             // nothing to do, no picture to display in the queue
1348         } else {
1349             double last_duration, duration, delay;
1350             /* dequeue the picture */
1351             vp = &is->pictq[is->pictq_rindex];
1352
1353             if (vp->serial != is->videoq.serial) {
1354                 pictq_next_picture(is);
1355                 redisplay = 0;
1356                 goto retry;
1357             }
1358
1359             if (is->paused)
1360                 goto display;
1361
1362             /* compute nominal last_duration */
1363             last_duration = vp->pts - is->frame_last_pts;
1364             if (last_duration > 0 && last_duration < is->max_frame_duration) {
1365                 /* if duration of the last frame was sane, update last_duration in video state */
1366                 is->frame_last_duration = last_duration;
1367             }
1368             delay = compute_target_delay(is->frame_last_duration, is);
1369
1370             time= av_gettime()/1000000.0;
1371             if (time < is->frame_timer + delay) {
1372                 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1373                 return;
1374             }
1375
1376             if (delay > 0)
1377                 is->frame_timer += delay * FFMAX(1, floor((time-is->frame_timer) / delay));
1378
1379             SDL_LockMutex(is->pictq_mutex);
1380             update_video_pts(is, vp->pts, vp->pos, vp->serial);
1381             SDL_UnlockMutex(is->pictq_mutex);
1382
1383             if (is->pictq_size > 1) {
1384                 VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
1385                 duration = nextvp->pts - vp->pts;
1386                 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1387                     if (!redisplay)
1388                         is->frame_drops_late++;
1389                     pictq_next_picture(is);
1390                     redisplay = 0;
1391                     goto retry;
1392                 }
1393             }
1394
1395             if (is->subtitle_st) {
1396                 if (is->subtitle_stream_changed) {
1397                     SDL_LockMutex(is->subpq_mutex);
1398
1399                     while (is->subpq_size) {
1400                         free_subpicture(&is->subpq[is->subpq_rindex]);
1401
1402                         /* update queue size and signal for next picture */
1403                         if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1404                             is->subpq_rindex = 0;
1405
1406                         is->subpq_size--;
1407                     }
1408                     is->subtitle_stream_changed = 0;
1409
1410                     SDL_CondSignal(is->subpq_cond);
1411                     SDL_UnlockMutex(is->subpq_mutex);
1412                 } else {
1413                     if (is->subpq_size > 0) {
1414                         sp = &is->subpq[is->subpq_rindex];
1415
1416                         if (is->subpq_size > 1)
1417                             sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1418                         else
1419                             sp2 = NULL;
1420
1421                         if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1422                                 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1423                         {
1424                             free_subpicture(sp);
1425
1426                             /* update queue size and signal for next picture */
1427                             if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1428                                 is->subpq_rindex = 0;
1429
1430                             SDL_LockMutex(is->subpq_mutex);
1431                             is->subpq_size--;
1432                             SDL_CondSignal(is->subpq_cond);
1433                             SDL_UnlockMutex(is->subpq_mutex);
1434                         }
1435                     }
1436                 }
1437             }
1438
1439 display:
1440             /* display picture */
1441             if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1442                 video_display(is);
1443
1444             pictq_next_picture(is);
1445
1446             if (is->step && !is->paused)
1447                 stream_toggle_pause(is);
1448         }
1449     }
1450     is->force_refresh = 0;
1451     if (show_status) {
1452         static int64_t last_time;
1453         int64_t cur_time;
1454         int aqsize, vqsize, sqsize;
1455         double av_diff;
1456
1457         cur_time = av_gettime();
1458         if (!last_time || (cur_time - last_time) >= 30000) {
1459             aqsize = 0;
1460             vqsize = 0;
1461             sqsize = 0;
1462             if (is->audio_st)
1463                 aqsize = is->audioq.size;
1464             if (is->video_st)
1465                 vqsize = is->videoq.size;
1466             if (is->subtitle_st)
1467                 sqsize = is->subtitleq.size;
1468             av_diff = 0;
1469             if (is->audio_st && is->video_st)
1470                 av_diff = get_audio_clock(is) - get_video_clock(is);
1471             printf("%7.2f A-V:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
1472                    get_master_clock(is),
1473                    av_diff,
1474                    is->frame_drops_early + is->frame_drops_late,
1475                    aqsize / 1024,
1476                    vqsize / 1024,
1477                    sqsize,
1478                    is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1479                    is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1480             fflush(stdout);
1481             last_time = cur_time;
1482         }
1483     }
1484 }
1485
1486 /* allocate a picture (needs to do that in main thread to avoid
1487    potential locking problems */
1488 static void alloc_picture(VideoState *is)
1489 {
1490     VideoPicture *vp;
1491
1492     vp = &is->pictq[is->pictq_windex];
1493
1494     if (vp->bmp)
1495         SDL_FreeYUVOverlay(vp->bmp);
1496
1497     video_open(is, 0, vp);
1498
1499     vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1500                                    SDL_YV12_OVERLAY,
1501                                    screen);
1502     if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
1503         /* SDL allocates a buffer smaller than requested if the video
1504          * overlay hardware is unable to support the requested size. */
1505         fprintf(stderr, "Error: the video system does not support an image\n"
1506                         "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1507                         "to reduce the image size.\n", vp->width, vp->height );
1508         do_exit(is);
1509     }
1510
1511     SDL_LockMutex(is->pictq_mutex);
1512     vp->allocated = 1;
1513     SDL_CondSignal(is->pictq_cond);
1514     SDL_UnlockMutex(is->pictq_mutex);
1515 }
1516
1517 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1518     int i, width, height;
1519     Uint8 *p, *maxp;
1520     for (i = 0; i < 3; i++) {
1521         width  = bmp->w;
1522         height = bmp->h;
1523         if (i > 0) {
1524             width  >>= 1;
1525             height >>= 1;
1526         }
1527         if (bmp->pitches[i] > width) {
1528             maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1529             for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1530                 *(p+1) = *p;
1531         }
1532     }
1533 }
1534
1535 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos, int serial)
1536 {
1537     VideoPicture *vp;
1538
1539 #if defined(DEBUG_SYNC) && 0
1540     printf("frame_type=%c pts=%0.3f\n",
1541            av_get_picture_type_char(src_frame->pict_type), pts);
1542 #endif
1543
1544     /* wait until we have space to put a new picture */
1545     SDL_LockMutex(is->pictq_mutex);
1546
1547     /* keep the last already displayed picture in the queue */
1548     while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE - 2 &&
1549            !is->videoq.abort_request) {
1550         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1551     }
1552     SDL_UnlockMutex(is->pictq_mutex);
1553
1554     if (is->videoq.abort_request)
1555         return -1;
1556
1557     vp = &is->pictq[is->pictq_windex];
1558
1559 #if CONFIG_AVFILTER
1560     vp->sar = src_frame->sample_aspect_ratio;
1561 #else
1562     vp->sar = av_guess_sample_aspect_ratio(is->ic, is->video_st, src_frame);
1563 #endif
1564
1565     /* alloc or resize hardware picture buffer */
1566     if (!vp->bmp || vp->reallocate || !vp->allocated ||
1567         vp->width  != src_frame->width ||
1568         vp->height != src_frame->height) {
1569         SDL_Event event;
1570
1571         vp->allocated  = 0;
1572         vp->reallocate = 0;
1573         vp->width = src_frame->width;
1574         vp->height = src_frame->height;
1575
1576         /* the allocation must be done in the main thread to avoid
1577            locking problems. */
1578         event.type = FF_ALLOC_EVENT;
1579         event.user.data1 = is;
1580         SDL_PushEvent(&event);
1581
1582         /* wait until the picture is allocated */
1583         SDL_LockMutex(is->pictq_mutex);
1584         while (!vp->allocated && !is->videoq.abort_request) {
1585             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1586         }
1587         /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1588         if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1589             while (!vp->allocated) {
1590                 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1591             }
1592         }
1593         SDL_UnlockMutex(is->pictq_mutex);
1594
1595         if (is->videoq.abort_request)
1596             return -1;
1597     }
1598
1599     /* if the frame is not skipped, then display it */
1600     if (vp->bmp) {
1601         AVPicture pict = { { 0 } };
1602
1603         /* get a pointer on the bitmap */
1604         SDL_LockYUVOverlay (vp->bmp);
1605
1606         pict.data[0] = vp->bmp->pixels[0];
1607         pict.data[1] = vp->bmp->pixels[2];
1608         pict.data[2] = vp->bmp->pixels[1];
1609
1610         pict.linesize[0] = vp->bmp->pitches[0];
1611         pict.linesize[1] = vp->bmp->pitches[2];
1612         pict.linesize[2] = vp->bmp->pitches[1];
1613
1614 #if CONFIG_AVFILTER
1615         // FIXME use direct rendering
1616         av_picture_copy(&pict, (AVPicture *)src_frame,
1617                         src_frame->format, vp->width, vp->height);
1618 #else
1619         av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1620         is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1621             vp->width, vp->height, src_frame->format, vp->width, vp->height,
1622             AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1623         if (is->img_convert_ctx == NULL) {
1624             fprintf(stderr, "Cannot initialize the conversion context\n");
1625             exit(1);
1626         }
1627         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1628                   0, vp->height, pict.data, pict.linesize);
1629 #endif
1630         /* workaround SDL PITCH_WORKAROUND */
1631         duplicate_right_border_pixels(vp->bmp);
1632         /* update the bitmap content */
1633         SDL_UnlockYUVOverlay(vp->bmp);
1634
1635         vp->pts = pts;
1636         vp->pos = pos;
1637         vp->serial = serial;
1638
1639         /* now we can update the picture count */
1640         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1641             is->pictq_windex = 0;
1642         SDL_LockMutex(is->pictq_mutex);
1643         is->pictq_size++;
1644         SDL_UnlockMutex(is->pictq_mutex);
1645     }
1646     return 0;
1647 }
1648
1649 static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *serial)
1650 {
1651     int got_picture;
1652
1653     if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
1654         return -1;
1655
1656     if (pkt->data == flush_pkt.data) {
1657         avcodec_flush_buffers(is->video_st->codec);
1658
1659         SDL_LockMutex(is->pictq_mutex);
1660         // Make sure there are no long delay timers (ideally we should just flush the queue but that's harder)
1661         while (is->pictq_size && !is->videoq.abort_request) {
1662             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1663         }
1664         is->video_current_pos = -1;
1665         is->frame_last_pts = AV_NOPTS_VALUE;
1666         is->frame_last_duration = 0;
1667         is->frame_timer = (double)av_gettime() / 1000000.0;
1668         is->frame_last_dropped_pts = AV_NOPTS_VALUE;
1669         SDL_UnlockMutex(is->pictq_mutex);
1670         return 0;
1671     }
1672
1673     if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
1674         return 0;
1675
1676     if (got_picture) {
1677         int ret = 1;
1678
1679         if (decoder_reorder_pts == -1) {
1680             frame->pts = av_frame_get_best_effort_timestamp(frame);
1681         } else if (decoder_reorder_pts) {
1682             frame->pts = frame->pkt_pts;
1683         } else {
1684             frame->pts = frame->pkt_dts;
1685         }
1686
1687         if (frame->pts == AV_NOPTS_VALUE) {
1688             frame->pts = 0;
1689         }
1690
1691         if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1692             SDL_LockMutex(is->pictq_mutex);
1693             if (is->frame_last_pts != AV_NOPTS_VALUE && frame->pts) {
1694                 double clockdiff = get_video_clock(is) - get_master_clock(is);
1695                 double dpts = av_q2d(is->video_st->time_base) * frame->pts;
1696                 double ptsdiff = dpts - is->frame_last_pts;
1697                 if (!isnan(clockdiff) && fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
1698                      ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
1699                      clockdiff + ptsdiff - is->frame_last_filter_delay < 0) {
1700                     is->frame_last_dropped_pos = pkt->pos;
1701                     is->frame_last_dropped_pts = dpts;
1702                     is->frame_last_dropped_serial = *serial;
1703                     is->frame_drops_early++;
1704                     av_frame_unref(frame);
1705                     ret = 0;
1706                 }
1707             }
1708             SDL_UnlockMutex(is->pictq_mutex);
1709         }
1710
1711         return ret;
1712     }
1713     return 0;
1714 }
1715
1716 #if CONFIG_AVFILTER
1717 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1718                                  AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1719 {
1720     int ret;
1721     AVFilterInOut *outputs = NULL, *inputs = NULL;
1722
1723     if (filtergraph) {
1724         outputs = avfilter_inout_alloc();
1725         inputs  = avfilter_inout_alloc();
1726         if (!outputs || !inputs) {
1727             ret = AVERROR(ENOMEM);
1728             goto fail;
1729         }
1730
1731         outputs->name       = av_strdup("in");
1732         outputs->filter_ctx = source_ctx;
1733         outputs->pad_idx    = 0;
1734         outputs->next       = NULL;
1735
1736         inputs->name        = av_strdup("out");
1737         inputs->filter_ctx  = sink_ctx;
1738         inputs->pad_idx     = 0;
1739         inputs->next        = NULL;
1740
1741         if ((ret = avfilter_graph_parse(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1742             goto fail;
1743     } else {
1744         if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1745             goto fail;
1746     }
1747
1748     ret = avfilter_graph_config(graph, NULL);
1749 fail:
1750     avfilter_inout_free(&outputs);
1751     avfilter_inout_free(&inputs);
1752     return ret;
1753 }
1754
1755 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1756 {
1757     static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1758     char sws_flags_str[128];
1759     char buffersrc_args[256];
1760     int ret;
1761     AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_crop;
1762     AVCodecContext *codec = is->video_st->codec;
1763     AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1764
1765     av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1766     snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1767     graph->scale_sws_opts = av_strdup(sws_flags_str);
1768
1769     snprintf(buffersrc_args, sizeof(buffersrc_args),
1770              "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1771              frame->width, frame->height, frame->format,
1772              is->video_st->time_base.num, is->video_st->time_base.den,
1773              codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1774     if (fr.num && fr.den)
1775         av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1776
1777     if ((ret = avfilter_graph_create_filter(&filt_src,
1778                                             avfilter_get_by_name("buffer"),
1779                                             "ffplay_buffer", buffersrc_args, NULL,
1780                                             graph)) < 0)
1781         goto fail;
1782
1783     ret = avfilter_graph_create_filter(&filt_out,
1784                                        avfilter_get_by_name("buffersink"),
1785                                        "ffplay_buffersink", NULL, NULL, graph);
1786     if (ret < 0)
1787         goto fail;
1788
1789     if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts,  AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1790         goto fail;
1791
1792     /* SDL YUV code is not handling odd width/height for some driver
1793      * combinations, therefore we crop the picture to an even width/height. */
1794     if ((ret = avfilter_graph_create_filter(&filt_crop,
1795                                             avfilter_get_by_name("crop"),
1796                                             "ffplay_crop", "floor(in_w/2)*2:floor(in_h/2)*2", NULL, graph)) < 0)
1797         goto fail;
1798     if ((ret = avfilter_link(filt_crop, 0, filt_out, 0)) < 0)
1799         goto fail;
1800
1801     if ((ret = configure_filtergraph(graph, vfilters, filt_src, filt_crop)) < 0)
1802         goto fail;
1803
1804     is->in_video_filter  = filt_src;
1805     is->out_video_filter = filt_out;
1806
1807 fail:
1808     return ret;
1809 }
1810
1811 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1812 {
1813     static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1814     int sample_rates[2] = { 0, -1 };
1815     int64_t channel_layouts[2] = { 0, -1 };
1816     int channels[2] = { 0, -1 };
1817     AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1818     char asrc_args[256];
1819     int ret;
1820
1821     avfilter_graph_free(&is->agraph);
1822     if (!(is->agraph = avfilter_graph_alloc()))
1823         return AVERROR(ENOMEM);
1824
1825     ret = snprintf(asrc_args, sizeof(asrc_args),
1826                    "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1827                    is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1828                    is->audio_filter_src.channels,
1829                    1, is->audio_filter_src.freq);
1830     if (is->audio_filter_src.channel_layout)
1831         snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1832                  ":channel_layout=0x%"PRIx64,  is->audio_filter_src.channel_layout);
1833
1834     ret = avfilter_graph_create_filter(&filt_asrc,
1835                                        avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1836                                        asrc_args, NULL, is->agraph);
1837     if (ret < 0)
1838         goto end;
1839
1840
1841     ret = avfilter_graph_create_filter(&filt_asink,
1842                                        avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1843                                        NULL, NULL, is->agraph);
1844     if (ret < 0)
1845         goto end;
1846
1847     if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts,  AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1848         goto end;
1849     if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1850         goto end;
1851
1852     if (force_output_format) {
1853         channel_layouts[0] = is->audio_tgt.channel_layout;
1854         channels       [0] = is->audio_tgt.channels;
1855         sample_rates   [0] = is->audio_tgt.freq;
1856         if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1857             goto end;
1858         if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1859             goto end;
1860         if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels       ,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1861             goto end;
1862         if ((ret = av_opt_set_int_list(filt_asink, "sample_rates"   , sample_rates   ,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1863             goto end;
1864     }
1865
1866
1867     if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1868         goto end;
1869
1870     is->in_audio_filter  = filt_asrc;
1871     is->out_audio_filter = filt_asink;
1872
1873 end:
1874     if (ret < 0)
1875         avfilter_graph_free(&is->agraph);
1876     return ret;
1877 }
1878 #endif  /* CONFIG_AVFILTER */
1879
1880 static int video_thread(void *arg)
1881 {
1882     AVPacket pkt = { 0 };
1883     VideoState *is = arg;
1884     AVFrame *frame = av_frame_alloc();
1885     double pts;
1886     int ret;
1887     int serial = 0;
1888
1889 #if CONFIG_AVFILTER
1890     AVFilterGraph *graph = avfilter_graph_alloc();
1891     AVFilterContext *filt_out = NULL, *filt_in = NULL;
1892     int last_w = 0;
1893     int last_h = 0;
1894     enum AVPixelFormat last_format = -2;
1895     int last_serial = -1;
1896 #endif
1897
1898     for (;;) {
1899         while (is->paused && !is->videoq.abort_request)
1900             SDL_Delay(10);
1901
1902         avcodec_get_frame_defaults(frame);
1903         av_free_packet(&pkt);
1904
1905         ret = get_video_frame(is, frame, &pkt, &serial);
1906         if (ret < 0)
1907             goto the_end;
1908         if (!ret)
1909             continue;
1910
1911 #if CONFIG_AVFILTER
1912         if (   last_w != frame->width
1913             || last_h != frame->height
1914             || last_format != frame->format
1915             || last_serial != serial) {
1916             av_log(NULL, AV_LOG_DEBUG,
1917                    "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
1918                    last_w, last_h,
1919                    (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
1920                    frame->width, frame->height,
1921                    (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial);
1922             avfilter_graph_free(&graph);
1923             graph = avfilter_graph_alloc();
1924             if ((ret = configure_video_filters(graph, is, vfilters, frame)) < 0) {
1925                 SDL_Event event;
1926                 event.type = FF_QUIT_EVENT;
1927                 event.user.data1 = is;
1928                 SDL_PushEvent(&event);
1929                 av_free_packet(&pkt);
1930                 goto the_end;
1931             }
1932             filt_in  = is->in_video_filter;
1933             filt_out = is->out_video_filter;
1934             last_w = frame->width;
1935             last_h = frame->height;
1936             last_format = frame->format;
1937             last_serial = serial;
1938         }
1939
1940         frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1941         ret = av_buffersrc_add_frame(filt_in, frame);
1942         if (ret < 0)
1943             goto the_end;
1944         av_frame_unref(frame);
1945         avcodec_get_frame_defaults(frame);
1946         av_free_packet(&pkt);
1947
1948         while (ret >= 0) {
1949             is->frame_last_returned_time = av_gettime() / 1000000.0;
1950
1951             ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
1952             if (ret < 0) {
1953                 ret = 0;
1954                 break;
1955             }
1956
1957             is->frame_last_filter_delay = av_gettime() / 1000000.0 - is->frame_last_returned_time;
1958             if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
1959                 is->frame_last_filter_delay = 0;
1960
1961             pts = frame->pts * av_q2d(filt_out->inputs[0]->time_base);
1962             ret = queue_picture(is, frame, pts, av_frame_get_pkt_pos(frame), serial);
1963             av_frame_unref(frame);
1964         }
1965 #else
1966         pts = frame->pts * av_q2d(is->video_st->time_base);
1967         ret = queue_picture(is, frame, pts, pkt.pos, serial);
1968         av_frame_unref(frame);
1969 #endif
1970
1971         if (ret < 0)
1972             goto the_end;
1973     }
1974  the_end:
1975     avcodec_flush_buffers(is->video_st->codec);
1976 #if CONFIG_AVFILTER
1977     avfilter_graph_free(&graph);
1978 #endif
1979     av_free_packet(&pkt);
1980     av_frame_free(&frame);
1981     return 0;
1982 }
1983
1984 static int subtitle_thread(void *arg)
1985 {
1986     VideoState *is = arg;
1987     SubPicture *sp;
1988     AVPacket pkt1, *pkt = &pkt1;
1989     int got_subtitle;
1990     double pts;
1991     int i, j;
1992     int r, g, b, y, u, v, a;
1993
1994     for (;;) {
1995         while (is->paused && !is->subtitleq.abort_request) {
1996             SDL_Delay(10);
1997         }
1998         if (packet_queue_get(&is->subtitleq, pkt, 1, NULL) < 0)
1999             break;
2000
2001         if (pkt->data == flush_pkt.data) {
2002             avcodec_flush_buffers(is->subtitle_st->codec);
2003             continue;
2004         }
2005         SDL_LockMutex(is->subpq_mutex);
2006         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
2007                !is->subtitleq.abort_request) {
2008             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
2009         }
2010         SDL_UnlockMutex(is->subpq_mutex);
2011
2012         if (is->subtitleq.abort_request)
2013             return 0;
2014
2015         sp = &is->subpq[is->subpq_windex];
2016
2017        /* NOTE: ipts is the PTS of the _first_ picture beginning in
2018            this packet, if any */
2019         pts = 0;
2020         if (pkt->pts != AV_NOPTS_VALUE)
2021             pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
2022
2023         avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
2024                                  &got_subtitle, pkt);
2025         if (got_subtitle && sp->sub.format == 0) {
2026             if (sp->sub.pts != AV_NOPTS_VALUE)
2027                 pts = sp->sub.pts / (double)AV_TIME_BASE;
2028             sp->pts = pts;
2029
2030             for (i = 0; i < sp->sub.num_rects; i++)
2031             {
2032                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2033                 {
2034                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2035                     y = RGB_TO_Y_CCIR(r, g, b);
2036                     u = RGB_TO_U_CCIR(r, g, b, 0);
2037                     v = RGB_TO_V_CCIR(r, g, b, 0);
2038                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2039                 }
2040             }
2041
2042             /* now we can update the picture count */
2043             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
2044                 is->subpq_windex = 0;
2045             SDL_LockMutex(is->subpq_mutex);
2046             is->subpq_size++;
2047             SDL_UnlockMutex(is->subpq_mutex);
2048         }
2049         av_free_packet(pkt);
2050     }
2051     return 0;
2052 }
2053
2054 /* copy samples for viewing in editor window */
2055 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2056 {
2057     int size, len;
2058
2059     size = samples_size / sizeof(short);
2060     while (size > 0) {
2061         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2062         if (len > size)
2063             len = size;
2064         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2065         samples += len;
2066         is->sample_array_index += len;
2067         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2068             is->sample_array_index = 0;
2069         size -= len;
2070     }
2071 }
2072
2073 /* return the wanted number of samples to get better sync if sync_type is video
2074  * or external master clock */
2075 static int synchronize_audio(VideoState *is, int nb_samples)
2076 {
2077     int wanted_nb_samples = nb_samples;
2078
2079     /* if not master, then we try to remove or add samples to correct the clock */
2080     if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2081         double diff, avg_diff;
2082         int min_nb_samples, max_nb_samples;
2083
2084         diff = get_audio_clock(is) - get_master_clock(is);
2085
2086         if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2087             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2088             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2089                 /* not enough measures to have a correct estimate */
2090                 is->audio_diff_avg_count++;
2091             } else {
2092                 /* estimate the A-V difference */
2093                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2094
2095                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2096                     wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2097                     min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2098                     max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2099                     wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2100                 }
2101                 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2102                         diff, avg_diff, wanted_nb_samples - nb_samples,
2103                         is->audio_clock, is->audio_diff_threshold);
2104             }
2105         } else {
2106             /* too big difference : may be initial PTS errors, so
2107                reset A-V filter */
2108             is->audio_diff_avg_count = 0;
2109             is->audio_diff_cum       = 0;
2110         }
2111     }
2112
2113     return wanted_nb_samples;
2114 }
2115
2116 /**
2117  * Decode one audio frame and return its uncompressed size.
2118  *
2119  * The processed audio frame is decoded, converted if required, and
2120  * stored in is->audio_buf, with size in bytes given by the return
2121  * value.
2122  */
2123 static int audio_decode_frame(VideoState *is)
2124 {
2125     AVPacket *pkt_temp = &is->audio_pkt_temp;
2126     AVPacket *pkt = &is->audio_pkt;
2127     AVCodecContext *dec = is->audio_st->codec;
2128     int len1, data_size, resampled_data_size;
2129     int64_t dec_channel_layout;
2130     int got_frame;
2131     av_unused double audio_clock0;
2132     int new_packet = 0;
2133     int flush_complete = 0;
2134     int wanted_nb_samples;
2135     AVRational tb;
2136     int ret;
2137     int reconfigure;
2138
2139     for (;;) {
2140         /* NOTE: the audio packet can contain several frames */
2141         while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet) || is->audio_buf_frames_pending) {
2142             if (!is->frame) {
2143                 if (!(is->frame = avcodec_alloc_frame()))
2144                     return AVERROR(ENOMEM);
2145             } else {
2146                 av_frame_unref(is->frame);
2147                 avcodec_get_frame_defaults(is->frame);
2148             }
2149
2150             if (is->audioq.serial != is->audio_pkt_temp_serial)
2151                 break;
2152
2153             if (is->paused)
2154                 return -1;
2155
2156             if (!is->audio_buf_frames_pending) {
2157                 if (flush_complete)
2158                     break;
2159                 new_packet = 0;
2160                 len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2161                 if (len1 < 0) {
2162                     /* if error, we skip the frame */
2163                     pkt_temp->size = 0;
2164                     break;
2165                 }
2166
2167                 pkt_temp->data += len1;
2168                 pkt_temp->size -= len1;
2169
2170                 if (!got_frame) {
2171                     /* stop sending empty packets if the decoder is finished */
2172                     if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
2173                         flush_complete = 1;
2174                     continue;
2175                 }
2176
2177                 tb = (AVRational){1, is->frame->sample_rate};
2178                 if (is->frame->pts != AV_NOPTS_VALUE)
2179                     is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
2180                 if (is->frame->pts == AV_NOPTS_VALUE && pkt_temp->pts != AV_NOPTS_VALUE)
2181                     is->frame->pts = av_rescale_q(pkt_temp->pts, is->audio_st->time_base, tb);
2182                 if (pkt_temp->pts != AV_NOPTS_VALUE)
2183                     pkt_temp->pts += (double) is->frame->nb_samples / is->frame->sample_rate / av_q2d(is->audio_st->time_base);
2184
2185 #if CONFIG_AVFILTER
2186                 dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
2187
2188                 reconfigure =
2189                     cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2190                                    is->frame->format, av_frame_get_channels(is->frame))    ||
2191                     is->audio_filter_src.channel_layout != dec_channel_layout ||
2192                     is->audio_filter_src.freq           != is->frame->sample_rate ||
2193                     is->audio_pkt_temp_serial           != is->audio_last_serial;
2194
2195                 if (reconfigure) {
2196                     char buf1[1024], buf2[1024];
2197                     av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2198                     av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2199                     av_log(NULL, AV_LOG_DEBUG,
2200                            "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
2201                            is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, is->audio_last_serial,
2202                            is->frame->sample_rate, av_frame_get_channels(is->frame), av_get_sample_fmt_name(is->frame->format), buf2, is->audio_pkt_temp_serial);
2203
2204                     is->audio_filter_src.fmt            = is->frame->format;
2205                     is->audio_filter_src.channels       = av_frame_get_channels(is->frame);
2206                     is->audio_filter_src.channel_layout = dec_channel_layout;
2207                     is->audio_filter_src.freq           = is->frame->sample_rate;
2208                     is->audio_last_serial               = is->audio_pkt_temp_serial;
2209
2210                     if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2211                         return ret;
2212                 }
2213
2214                 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
2215                     return ret;
2216                 av_frame_unref(is->frame);
2217 #endif
2218             }
2219 #if CONFIG_AVFILTER
2220             if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
2221                 if (ret == AVERROR(EAGAIN)) {
2222                     is->audio_buf_frames_pending = 0;
2223                     continue;
2224                 }
2225                 return ret;
2226             }
2227             is->audio_buf_frames_pending = 1;
2228             tb = is->out_audio_filter->inputs[0]->time_base;
2229 #endif
2230
2231             data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
2232                                                    is->frame->nb_samples,
2233                                                    is->frame->format, 1);
2234
2235             dec_channel_layout =
2236                 (is->frame->channel_layout && av_frame_get_channels(is->frame) == av_get_channel_layout_nb_channels(is->frame->channel_layout)) ?
2237                 is->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(is->frame));
2238             wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2239
2240             if (is->frame->format        != is->audio_src.fmt            ||
2241                 dec_channel_layout       != is->audio_src.channel_layout ||
2242                 is->frame->sample_rate   != is->audio_src.freq           ||
2243                 (wanted_nb_samples       != is->frame->nb_samples && !is->swr_ctx)) {
2244                 swr_free(&is->swr_ctx);
2245                 is->swr_ctx = swr_alloc_set_opts(NULL,
2246                                                  is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2247                                                  dec_channel_layout,           is->frame->format, is->frame->sample_rate,
2248                                                  0, NULL);
2249                 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2250                     fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2251                             is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
2252                             is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2253                     break;
2254                 }
2255                 is->audio_src.channel_layout = dec_channel_layout;
2256                 is->audio_src.channels       = av_frame_get_channels(is->frame);
2257                 is->audio_src.freq = is->frame->sample_rate;
2258                 is->audio_src.fmt = is->frame->format;
2259             }
2260
2261             if (is->swr_ctx) {
2262                 const uint8_t **in = (const uint8_t **)is->frame->extended_data;
2263                 uint8_t **out = &is->audio_buf1;
2264                 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
2265                 int out_size  = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2266                 int len2;
2267                 if (wanted_nb_samples != is->frame->nb_samples) {
2268                     if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
2269                                                 wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
2270                         fprintf(stderr, "swr_set_compensation() failed\n");
2271                         break;
2272                     }
2273                 }
2274                 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2275                 if (!is->audio_buf1)
2276                     return AVERROR(ENOMEM);
2277                 len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
2278                 if (len2 < 0) {
2279                     fprintf(stderr, "swr_convert() failed\n");
2280                     break;
2281                 }
2282                 if (len2 == out_count) {
2283                     fprintf(stderr, "warning: audio buffer is probably too small\n");
2284                     swr_init(is->swr_ctx);
2285                 }
2286                 is->audio_buf = is->audio_buf1;
2287                 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2288             } else {
2289                 is->audio_buf = is->frame->data[0];
2290                 resampled_data_size = data_size;
2291             }
2292
2293             audio_clock0 = is->audio_clock;
2294             /* update the audio clock with the pts */
2295             if (is->frame->pts != AV_NOPTS_VALUE) {
2296                 is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
2297                 is->audio_clock_serial = is->audio_pkt_temp_serial;
2298             }
2299 #ifdef DEBUG
2300             {
2301                 static double last_clock;
2302                 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2303                        is->audio_clock - last_clock,
2304                        is->audio_clock, audio_clock0);
2305                 last_clock = is->audio_clock;
2306             }
2307 #endif
2308             return resampled_data_size;
2309         }
2310
2311         /* free the current packet */
2312         if (pkt->data)
2313             av_free_packet(pkt);
2314         memset(pkt_temp, 0, sizeof(*pkt_temp));
2315
2316         if (is->audioq.abort_request) {
2317             return -1;
2318         }
2319
2320         if (is->audioq.nb_packets == 0)
2321             SDL_CondSignal(is->continue_read_thread);
2322
2323         /* read next packet */
2324         if ((new_packet = packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
2325             return -1;
2326
2327         if (pkt->data == flush_pkt.data) {
2328             avcodec_flush_buffers(dec);
2329             flush_complete = 0;
2330             is->audio_buf_frames_pending = 0;
2331         }
2332
2333         *pkt_temp = *pkt;
2334     }
2335 }
2336
2337 /* prepare a new audio buffer */
2338 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2339 {
2340     VideoState *is = opaque;
2341     int audio_size, len1;
2342     int bytes_per_sec;
2343     int frame_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, 1, is->audio_tgt.fmt, 1);
2344
2345     audio_callback_time = av_gettime();
2346
2347     while (len > 0) {
2348         if (is->audio_buf_index >= is->audio_buf_size) {
2349            audio_size = audio_decode_frame(is);
2350            if (audio_size < 0) {
2351                 /* if error, just output silence */
2352                is->audio_buf      = is->silence_buf;
2353                is->audio_buf_size = sizeof(is->silence_buf) / frame_size * frame_size;
2354            } else {
2355                if (is->show_mode != SHOW_MODE_VIDEO)
2356                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2357                is->audio_buf_size = audio_size;
2358            }
2359            is->audio_buf_index = 0;
2360         }
2361         len1 = is->audio_buf_size - is->audio_buf_index;
2362         if (len1 > len)
2363             len1 = len;
2364         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2365         len -= len1;
2366         stream += len1;
2367         is->audio_buf_index += len1;
2368     }
2369     bytes_per_sec = is->audio_tgt.freq * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2370     is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2371     /* Let's assume the audio driver that is used by SDL has two periods. */
2372     is->audio_current_pts = is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec;
2373     is->audio_current_pts_drift = is->audio_current_pts - audio_callback_time / 1000000.0;
2374     if (is->audioq.serial == is->audio_clock_serial)
2375         check_external_clock_sync(is, is->audio_current_pts);
2376 }
2377
2378 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2379 {
2380     SDL_AudioSpec wanted_spec, spec;
2381     const char *env;
2382     const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2383
2384     env = SDL_getenv("SDL_AUDIO_CHANNELS");
2385     if (env) {
2386         wanted_nb_channels = atoi(env);
2387         wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2388     }
2389     if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2390         wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2391         wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2392     }
2393     wanted_spec.channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2394     wanted_spec.freq = wanted_sample_rate;
2395     if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2396         fprintf(stderr, "Invalid sample rate or channel count!\n");
2397         return -1;
2398     }
2399     wanted_spec.format = AUDIO_S16SYS;
2400     wanted_spec.silence = 0;
2401     wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2402     wanted_spec.callback = sdl_audio_callback;
2403     wanted_spec.userdata = opaque;
2404     while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2405         fprintf(stderr, "SDL_OpenAudio (%d channels): %s\n", wanted_spec.channels, SDL_GetError());
2406         wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2407         if (!wanted_spec.channels) {
2408             fprintf(stderr, "No more channel combinations to try, audio open failed\n");
2409             return -1;
2410         }
2411         wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2412     }
2413     if (spec.format != AUDIO_S16SYS) {
2414         fprintf(stderr, "SDL advised audio format %d is not supported!\n", spec.format);
2415         return -1;
2416     }
2417     if (spec.channels != wanted_spec.channels) {
2418         wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2419         if (!wanted_channel_layout) {
2420             fprintf(stderr, "SDL advised channel count %d is not supported!\n", spec.channels);
2421             return -1;
2422         }
2423     }
2424
2425     audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2426     audio_hw_params->freq = spec.freq;
2427     audio_hw_params->channel_layout = wanted_channel_layout;
2428     audio_hw_params->channels =  spec.channels;
2429     return spec.size;
2430 }
2431
2432 /* open a given stream. Return 0 if OK */
2433 static int stream_component_open(VideoState *is, int stream_index)
2434 {
2435     AVFormatContext *ic = is->ic;
2436     AVCodecContext *avctx;
2437     AVCodec *codec;
2438     const char *forced_codec_name = NULL;
2439     AVDictionary *opts;
2440     AVDictionaryEntry *t = NULL;
2441     int sample_rate, nb_channels;
2442     int64_t channel_layout;
2443     int ret;
2444
2445     if (stream_index < 0 || stream_index >= ic->nb_streams)
2446         return -1;
2447     avctx = ic->streams[stream_index]->codec;
2448
2449     codec = avcodec_find_decoder(avctx->codec_id);
2450
2451     switch(avctx->codec_type){
2452         case AVMEDIA_TYPE_AUDIO   : is->last_audio_stream    = stream_index; forced_codec_name =    audio_codec_name; break;
2453         case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2454         case AVMEDIA_TYPE_VIDEO   : is->last_video_stream    = stream_index; forced_codec_name =    video_codec_name; break;
2455     }
2456     if (forced_codec_name)
2457         codec = avcodec_find_decoder_by_name(forced_codec_name);
2458     if (!codec) {
2459         if (forced_codec_name) fprintf(stderr, "No codec could be found with name '%s'\n", forced_codec_name);
2460         else                   fprintf(stderr, "No codec could be found with id %d\n", avctx->codec_id);
2461         return -1;
2462     }
2463
2464     avctx->codec_id = codec->id;
2465     avctx->workaround_bugs   = workaround_bugs;
2466     avctx->lowres            = lowres;
2467     if(avctx->lowres > codec->max_lowres){
2468         av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2469                 codec->max_lowres);
2470         avctx->lowres= codec->max_lowres;
2471     }
2472     avctx->idct_algo         = idct;
2473     avctx->error_concealment = error_concealment;
2474
2475     if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2476     if (fast)   avctx->flags2 |= CODEC_FLAG2_FAST;
2477     if(codec->capabilities & CODEC_CAP_DR1)
2478         avctx->flags |= CODEC_FLAG_EMU_EDGE;
2479
2480     opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2481     if (!av_dict_get(opts, "threads", NULL, 0))
2482         av_dict_set(&opts, "threads", "auto", 0);
2483     if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2484         av_dict_set(&opts, "refcounted_frames", "1", 0);
2485     if (avcodec_open2(avctx, codec, &opts) < 0)
2486         return -1;
2487     if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2488         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2489         return AVERROR_OPTION_NOT_FOUND;
2490     }
2491
2492     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2493     switch (avctx->codec_type) {
2494     case AVMEDIA_TYPE_AUDIO:
2495 #if CONFIG_AVFILTER
2496         {
2497             AVFilterLink *link;
2498
2499             is->audio_filter_src.freq           = avctx->sample_rate;
2500             is->audio_filter_src.channels       = avctx->channels;
2501             is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2502             is->audio_filter_src.fmt            = avctx->sample_fmt;
2503             if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2504                 return ret;
2505             link = is->out_audio_filter->inputs[0];
2506             sample_rate    = link->sample_rate;
2507             nb_channels    = link->channels;
2508             channel_layout = link->channel_layout;
2509         }
2510 #else
2511         sample_rate    = avctx->sample_rate;
2512         nb_channels    = avctx->channels;
2513         channel_layout = avctx->channel_layout;
2514 #endif
2515
2516         /* prepare audio output */
2517         if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2518             return ret;
2519         is->audio_hw_buf_size = ret;
2520         is->audio_src = is->audio_tgt;
2521         is->audio_buf_size  = 0;
2522         is->audio_buf_index = 0;
2523
2524         /* init averaging filter */
2525         is->audio_diff_avg_coef  = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2526         is->audio_diff_avg_count = 0;
2527         /* since we do not have a precise anough audio fifo fullness,
2528            we correct audio sync only if larger than this threshold */
2529         is->audio_diff_threshold = 2.0 * is->audio_hw_buf_size / av_samples_get_buffer_size(NULL, is->audio_tgt.channels, is->audio_tgt.freq, is->audio_tgt.fmt, 1);
2530
2531         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2532         memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
2533
2534         is->audio_stream = stream_index;
2535         is->audio_st = ic->streams[stream_index];
2536
2537         packet_queue_start(&is->audioq);
2538         SDL_PauseAudio(0);
2539         break;
2540     case AVMEDIA_TYPE_VIDEO:
2541         is->video_stream = stream_index;
2542         is->video_st = ic->streams[stream_index];
2543
2544         packet_queue_start(&is->videoq);
2545         is->video_tid = SDL_CreateThread(video_thread, is);
2546         is->queue_attachments_req = 1;
2547         break;
2548     case AVMEDIA_TYPE_SUBTITLE:
2549         is->subtitle_stream = stream_index;
2550         is->subtitle_st = ic->streams[stream_index];
2551         packet_queue_start(&is->subtitleq);
2552
2553         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2554         break;
2555     default:
2556         break;
2557     }
2558     return 0;
2559 }
2560
2561 static void stream_component_close(VideoState *is, int stream_index)
2562 {
2563     AVFormatContext *ic = is->ic;
2564     AVCodecContext *avctx;
2565
2566     if (stream_index < 0 || stream_index >= ic->nb_streams)
2567         return;
2568     avctx = ic->streams[stream_index]->codec;
2569
2570     switch (avctx->codec_type) {
2571     case AVMEDIA_TYPE_AUDIO:
2572         packet_queue_abort(&is->audioq);
2573
2574         SDL_CloseAudio();
2575
2576         packet_queue_flush(&is->audioq);
2577         av_free_packet(&is->audio_pkt);
2578         swr_free(&is->swr_ctx);
2579         av_freep(&is->audio_buf1);
2580         is->audio_buf1_size = 0;
2581         is->audio_buf = NULL;
2582         av_frame_free(&is->frame);
2583
2584         if (is->rdft) {
2585             av_rdft_end(is->rdft);
2586             av_freep(&is->rdft_data);
2587             is->rdft = NULL;
2588             is->rdft_bits = 0;
2589         }
2590 #if CONFIG_AVFILTER
2591         avfilter_graph_free(&is->agraph);
2592 #endif
2593         break;
2594     case AVMEDIA_TYPE_VIDEO:
2595         packet_queue_abort(&is->videoq);
2596
2597         /* note: we also signal this mutex to make sure we deblock the
2598            video thread in all cases */
2599         SDL_LockMutex(is->pictq_mutex);
2600         SDL_CondSignal(is->pictq_cond);
2601         SDL_UnlockMutex(is->pictq_mutex);
2602
2603         SDL_WaitThread(is->video_tid, NULL);
2604
2605         packet_queue_flush(&is->videoq);
2606         break;
2607     case AVMEDIA_TYPE_SUBTITLE:
2608         packet_queue_abort(&is->subtitleq);
2609
2610         /* note: we also signal this mutex to make sure we deblock the
2611            video thread in all cases */
2612         SDL_LockMutex(is->subpq_mutex);
2613         is->subtitle_stream_changed = 1;
2614
2615         SDL_CondSignal(is->subpq_cond);
2616         SDL_UnlockMutex(is->subpq_mutex);
2617
2618         SDL_WaitThread(is->subtitle_tid, NULL);
2619
2620         packet_queue_flush(&is->subtitleq);
2621         break;
2622     default:
2623         break;
2624     }
2625
2626     ic->streams[stream_index]->discard = AVDISCARD_ALL;
2627     avcodec_close(avctx);
2628     switch (avctx->codec_type) {
2629     case AVMEDIA_TYPE_AUDIO:
2630         is->audio_st = NULL;
2631         is->audio_stream = -1;
2632         break;
2633     case AVMEDIA_TYPE_VIDEO:
2634         is->video_st = NULL;
2635         is->video_stream = -1;
2636         break;
2637     case AVMEDIA_TYPE_SUBTITLE:
2638         is->subtitle_st = NULL;
2639         is->subtitle_stream = -1;
2640         break;
2641     default:
2642         break;
2643     }
2644 }
2645
2646 static int decode_interrupt_cb(void *ctx)
2647 {
2648     VideoState *is = ctx;
2649     return is->abort_request;
2650 }
2651
2652 static int is_realtime(AVFormatContext *s)
2653 {
2654     if(   !strcmp(s->iformat->name, "rtp")
2655        || !strcmp(s->iformat->name, "rtsp")
2656        || !strcmp(s->iformat->name, "sdp")
2657     )
2658         return 1;
2659
2660     if(s->pb && (   !strncmp(s->filename, "rtp:", 4)
2661                  || !strncmp(s->filename, "udp:", 4)
2662                 )
2663     )
2664         return 1;
2665     return 0;
2666 }
2667
2668 /* this thread gets the stream from the disk or the network */
2669 static int read_thread(void *arg)
2670 {
2671     VideoState *is = arg;
2672     AVFormatContext *ic = NULL;
2673     int err, i, ret;
2674     int st_index[AVMEDIA_TYPE_NB];
2675     AVPacket pkt1, *pkt = &pkt1;
2676     int eof = 0;
2677     int pkt_in_play_range = 0;
2678     AVDictionaryEntry *t;
2679     AVDictionary **opts;
2680     int orig_nb_streams;
2681     SDL_mutex *wait_mutex = SDL_CreateMutex();
2682
2683     memset(st_index, -1, sizeof(st_index));
2684     is->last_video_stream = is->video_stream = -1;
2685     is->last_audio_stream = is->audio_stream = -1;
2686     is->last_subtitle_stream = is->subtitle_stream = -1;
2687
2688     ic = avformat_alloc_context();
2689     ic->interrupt_callback.callback = decode_interrupt_cb;
2690     ic->interrupt_callback.opaque = is;
2691     err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2692     if (err < 0) {
2693         print_error(is->filename, err);
2694         ret = -1;
2695         goto fail;
2696     }
2697     if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2698         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2699         ret = AVERROR_OPTION_NOT_FOUND;
2700         goto fail;
2701     }
2702     is->ic = ic;
2703
2704     if (genpts)
2705         ic->flags |= AVFMT_FLAG_GENPTS;
2706
2707     opts = setup_find_stream_info_opts(ic, codec_opts);
2708     orig_nb_streams = ic->nb_streams;
2709
2710     err = avformat_find_stream_info(ic, opts);
2711     if (err < 0) {
2712         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2713         ret = -1;
2714         goto fail;
2715     }
2716     for (i = 0; i < orig_nb_streams; i++)
2717         av_dict_free(&opts[i]);
2718     av_freep(&opts);
2719
2720     if (ic->pb)
2721         ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
2722
2723     if (seek_by_bytes < 0)
2724         seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2725
2726     is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2727
2728     /* if seeking requested, we execute it */
2729     if (start_time != AV_NOPTS_VALUE) {
2730         int64_t timestamp;
2731
2732         timestamp = start_time;
2733         /* add the stream start time */
2734         if (ic->start_time != AV_NOPTS_VALUE)
2735             timestamp += ic->start_time;
2736         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2737         if (ret < 0) {
2738             fprintf(stderr, "%s: could not seek to position %0.3f\n",
2739                     is->filename, (double)timestamp / AV_TIME_BASE);
2740         }
2741     }
2742
2743     is->realtime = is_realtime(ic);
2744
2745     for (i = 0; i < ic->nb_streams; i++)
2746         ic->streams[i]->discard = AVDISCARD_ALL;
2747     if (!video_disable)
2748         st_index[AVMEDIA_TYPE_VIDEO] =
2749             av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2750                                 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2751     if (!audio_disable)
2752         st_index[AVMEDIA_TYPE_AUDIO] =
2753             av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2754                                 wanted_stream[AVMEDIA_TYPE_AUDIO],
2755                                 st_index[AVMEDIA_TYPE_VIDEO],
2756                                 NULL, 0);
2757     if (!video_disable && !subtitle_disable)
2758         st_index[AVMEDIA_TYPE_SUBTITLE] =
2759             av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2760                                 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2761                                 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2762                                  st_index[AVMEDIA_TYPE_AUDIO] :
2763                                  st_index[AVMEDIA_TYPE_VIDEO]),
2764                                 NULL, 0);
2765     if (show_status) {
2766         av_dump_format(ic, 0, is->filename, 0);
2767     }
2768
2769     is->show_mode = show_mode;
2770
2771     /* open the streams */
2772     if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2773         stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2774     }
2775
2776     ret = -1;
2777     if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2778         ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2779     }
2780     if (is->show_mode == SHOW_MODE_NONE)
2781         is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2782
2783     if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2784         stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2785     }
2786
2787     if (is->video_stream < 0 && is->audio_stream < 0) {
2788         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2789         ret = -1;
2790         goto fail;
2791     }
2792
2793     if (infinite_buffer < 0 && is->realtime)
2794         infinite_buffer = 1;
2795
2796     for (;;) {
2797         if (is->abort_request)
2798             break;
2799         if (is->paused != is->last_paused) {
2800             is->last_paused = is->paused;
2801             if (is->paused)
2802                 is->read_pause_return = av_read_pause(ic);
2803             else
2804                 av_read_play(ic);
2805         }
2806 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2807         if (is->paused &&
2808                 (!strcmp(ic->iformat->name, "rtsp") ||
2809                  (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2810             /* wait 10 ms to avoid trying to get another packet */
2811             /* XXX: horrible */
2812             SDL_Delay(10);
2813             continue;
2814         }
2815 #endif
2816         if (is->seek_req) {
2817             int64_t seek_target = is->seek_pos;
2818             int64_t seek_min    = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2819             int64_t seek_max    = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2820 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2821 //      of the seek_pos/seek_rel variables
2822
2823             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2824             if (ret < 0) {
2825                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2826             } else {
2827                 if (is->audio_stream >= 0) {
2828                     packet_queue_flush(&is->audioq);
2829                     packet_queue_put(&is->audioq, &flush_pkt);
2830                 }
2831                 if (is->subtitle_stream >= 0) {
2832                     packet_queue_flush(&is->subtitleq);
2833                     packet_queue_put(&is->subtitleq, &flush_pkt);
2834                 }
2835                 if (is->video_stream >= 0) {
2836                     packet_queue_flush(&is->videoq);
2837                     packet_queue_put(&is->videoq, &flush_pkt);
2838                 }
2839                 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2840                    update_external_clock_pts(is, NAN);
2841                 } else {
2842                    update_external_clock_pts(is, seek_target / (double)AV_TIME_BASE);
2843                 }
2844             }
2845             is->seek_req = 0;
2846             is->queue_attachments_req = 1;
2847             eof = 0;
2848             if (is->paused)
2849                 step_to_next_frame(is);
2850         }
2851         if (is->queue_attachments_req) {
2852             if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2853                 AVPacket copy;
2854                 if ((ret = av_copy_packet(&copy, &is->video_st->attached_pic)) < 0)
2855                     goto fail;
2856                 packet_queue_put(&is->videoq, &copy);
2857             }
2858             is->queue_attachments_req = 0;
2859         }
2860
2861         /* if the queue are full, no need to read more */
2862         if (infinite_buffer<1 &&
2863               (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2864             || (   (is->audioq   .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
2865                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
2866                     || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
2867                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
2868             /* wait 10 ms */
2869             SDL_LockMutex(wait_mutex);
2870             SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2871             SDL_UnlockMutex(wait_mutex);
2872             continue;
2873         }
2874         if (eof) {
2875             if (is->video_stream >= 0) {
2876                 av_init_packet(pkt);
2877                 pkt->data = NULL;
2878                 pkt->size = 0;
2879                 pkt->stream_index = is->video_stream;
2880                 packet_queue_put(&is->videoq, pkt);
2881             }
2882             if (is->audio_stream >= 0 &&
2883                 is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
2884                 av_init_packet(pkt);
2885                 pkt->data = NULL;
2886                 pkt->size = 0;
2887                 pkt->stream_index = is->audio_stream;
2888                 packet_queue_put(&is->audioq, pkt);
2889             }
2890             SDL_Delay(10);
2891             if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
2892                 if (loop != 1 && (!loop || --loop)) {
2893                     stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2894                 } else if (autoexit) {
2895                     ret = AVERROR_EOF;
2896                     goto fail;
2897                 }
2898             }
2899             eof=0;
2900             continue;
2901         }
2902         ret = av_read_frame(ic, pkt);
2903         if (ret < 0) {
2904             if (ret == AVERROR_EOF || url_feof(ic->pb))
2905                 eof = 1;
2906             if (ic->pb && ic->pb->error)
2907                 break;
2908             SDL_LockMutex(wait_mutex);
2909             SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2910             SDL_UnlockMutex(wait_mutex);
2911             continue;
2912         }
2913         /* check if packet is in play range specified by user, then queue, otherwise discard */
2914         pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2915                 (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
2916                 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2917                 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2918                 <= ((double)duration / 1000000);
2919         if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2920             packet_queue_put(&is->audioq, pkt);
2921         } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2922                    && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
2923             packet_queue_put(&is->videoq, pkt);
2924         } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2925             packet_queue_put(&is->subtitleq, pkt);
2926         } else {
2927             av_free_packet(pkt);
2928         }
2929     }
2930     /* wait until the end */
2931     while (!is->abort_request) {
2932         SDL_Delay(100);
2933     }
2934
2935     ret = 0;
2936  fail:
2937     /* close each stream */
2938     if (is->audio_stream >= 0)
2939         stream_component_close(is, is->audio_stream);
2940     if (is->video_stream >= 0)
2941         stream_component_close(is, is->video_stream);
2942     if (is->subtitle_stream >= 0)
2943         stream_component_close(is, is->subtitle_stream);
2944     if (is->ic) {
2945         avformat_close_input(&is->ic);
2946     }
2947
2948     if (ret != 0) {
2949         SDL_Event event;
2950
2951         event.type = FF_QUIT_EVENT;
2952         event.user.data1 = is;
2953         SDL_PushEvent(&event);
2954     }
2955     SDL_DestroyMutex(wait_mutex);
2956     return 0;
2957 }
2958
2959 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2960 {
2961     VideoState *is;
2962
2963     is = av_mallocz(sizeof(VideoState));
2964     if (!is)
2965         return NULL;
2966     av_strlcpy(is->filename, filename, sizeof(is->filename));
2967     is->iformat = iformat;
2968     is->ytop    = 0;
2969     is->xleft   = 0;
2970
2971     /* start video display */
2972     is->pictq_mutex = SDL_CreateMutex();
2973     is->pictq_cond  = SDL_CreateCond();
2974
2975     is->subpq_mutex = SDL_CreateMutex();
2976     is->subpq_cond  = SDL_CreateCond();
2977
2978     packet_queue_init(&is->videoq);
2979     packet_queue_init(&is->audioq);
2980     packet_queue_init(&is->subtitleq);
2981
2982     is->continue_read_thread = SDL_CreateCond();
2983
2984     update_external_clock_pts(is, NAN);
2985     update_external_clock_speed(is, 1.0);
2986     is->audio_current_pts_drift = -av_gettime() / 1000000.0;
2987     is->video_current_pts_drift = is->audio_current_pts_drift;
2988     is->audio_clock_serial = -1;
2989     is->video_clock_serial = -1;
2990     is->audio_last_serial = -1;
2991     is->av_sync_type = av_sync_type;
2992     is->read_tid     = SDL_CreateThread(read_thread, is);
2993     if (!is->read_tid) {
2994         av_free(is);
2995         return NULL;
2996     }
2997     return is;
2998 }
2999
3000 static void stream_cycle_channel(VideoState *is, int codec_type)
3001 {
3002     AVFormatContext *ic = is->ic;
3003     int start_index, stream_index;
3004     int old_index;
3005     AVStream *st;
3006
3007     if (codec_type == AVMEDIA_TYPE_VIDEO) {
3008         start_index = is->last_video_stream;
3009         old_index = is->video_stream;
3010     } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3011         start_index = is->last_audio_stream;
3012         old_index = is->audio_stream;
3013     } else {
3014         start_index = is->last_subtitle_stream;
3015         old_index = is->subtitle_stream;
3016     }
3017     stream_index = start_index;
3018     for (;;) {
3019         if (++stream_index >= is->ic->nb_streams)
3020         {
3021             if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3022             {
3023                 stream_index = -1;
3024                 is->last_subtitle_stream = -1;
3025                 goto the_end;
3026             }
3027             if (start_index == -1)
3028                 return;
3029             stream_index = 0;
3030         }
3031         if (stream_index == start_index)
3032             return;
3033         st = ic->streams[stream_index];
3034         if (st->codec->codec_type == codec_type) {
3035             /* check that parameters are OK */
3036             switch (codec_type) {
3037             case AVMEDIA_TYPE_AUDIO:
3038                 if (st->codec->sample_rate != 0 &&
3039                     st->codec->channels != 0)
3040                     goto the_end;
3041                 break;
3042             case AVMEDIA_TYPE_VIDEO:
3043             case AVMEDIA_TYPE_SUBTITLE:
3044                 goto the_end;
3045             default:
3046                 break;
3047             }
3048         }
3049     }
3050  the_end:
3051     stream_component_close(is, old_index);
3052     stream_component_open(is, stream_index);
3053 }
3054
3055
3056 static void toggle_full_screen(VideoState *is)
3057 {
3058 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3059     /* OS X needs to reallocate the SDL overlays */
3060     int i;
3061     for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3062         is->pictq[i].reallocate = 1;
3063 #endif
3064     is_full_screen = !is_full_screen;
3065     video_open(is, 1, NULL);
3066 }
3067
3068 static void toggle_audio_display(VideoState *is)
3069 {
3070     int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3071     int next = is->show_mode;
3072     do {
3073         next = (next + 1) % SHOW_MODE_NB;
3074     } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3075     if (is->show_mode != next) {
3076         fill_rectangle(screen,
3077                     is->xleft, is->ytop, is->width, is->height,
3078                     bgcolor, 1);
3079         is->force_refresh = 1;
3080         is->show_mode = next;
3081     }
3082 }
3083
3084 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3085     double remaining_time = 0.0;
3086     SDL_PumpEvents();
3087     while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3088         if (!cursor_hidden && av_gettime() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3089             SDL_ShowCursor(0);
3090             cursor_hidden = 1;
3091         }
3092         if (remaining_time > 0.0)
3093             av_usleep((int64_t)(remaining_time * 1000000.0));
3094         remaining_time = REFRESH_RATE;
3095         if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3096             video_refresh(is, &remaining_time);
3097         SDL_PumpEvents();
3098     }
3099 }
3100
3101 /* handle an event sent by the GUI */
3102 static void event_loop(VideoState *cur_stream)
3103 {
3104     SDL_Event event;
3105     double incr, pos, frac;
3106
3107     for (;;) {
3108         double x;
3109         refresh_loop_wait_event(cur_stream, &event);
3110         switch (event.type) {
3111         case SDL_KEYDOWN:
3112             if (exit_on_keydown) {
3113                 do_exit(cur_stream);
3114                 break;
3115             }
3116             switch (event.key.keysym.sym) {
3117             case SDLK_ESCAPE:
3118             case SDLK_q:
3119                 do_exit(cur_stream);
3120                 break;
3121             case SDLK_f:
3122                 toggle_full_screen(cur_stream);
3123                 cur_stream->force_refresh = 1;
3124                 break;
3125             case SDLK_p:
3126             case SDLK_SPACE:
3127                 toggle_pause(cur_stream);
3128                 break;
3129             case SDLK_s: // S: Step to next frame
3130                 step_to_next_frame(cur_stream);
3131                 break;
3132             case SDLK_a:
3133                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3134                 break;
3135             case SDLK_v:
3136                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3137                 break;
3138             case SDLK_t:
3139                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3140                 break;
3141             case SDLK_w:
3142                 toggle_audio_display(cur_stream);
3143                 break;
3144             case SDLK_PAGEUP:
3145                 incr = 600.0;
3146                 goto do_seek;
3147             case SDLK_PAGEDOWN:
3148                 incr = -600.0;
3149                 goto do_seek;
3150             case SDLK_LEFT:
3151                 incr = -10.0;
3152                 goto do_seek;
3153             case SDLK_RIGHT:
3154                 incr = 10.0;
3155                 goto do_seek;
3156             case SDLK_UP:
3157                 incr = 60.0;
3158                 goto do_seek;
3159             case SDLK_DOWN:
3160                 incr = -60.0;
3161             do_seek:
3162                     if (seek_by_bytes) {
3163                         if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
3164                             pos = cur_stream->video_current_pos;
3165                         } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
3166                             pos = cur_stream->audio_pkt.pos;
3167                         } else
3168                             pos = avio_tell(cur_stream->ic->pb);
3169                         if (cur_stream->ic->bit_rate)
3170                             incr *= cur_stream->ic->bit_rate / 8.0;
3171                         else
3172                             incr *= 180000.0;
3173                         pos += incr;
3174                         stream_seek(cur_stream, pos, incr, 1);
3175                     } else {
3176                         pos = get_master_clock(cur_stream);
3177                         if (isnan(pos))
3178                             pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3179                         pos += incr;
3180                         if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3181                             pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3182                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3183                     }
3184                 break;
3185             default:
3186                 break;
3187             }
3188             break;
3189         case SDL_VIDEOEXPOSE:
3190             cur_stream->force_refresh = 1;
3191             break;
3192         case SDL_MOUSEBUTTONDOWN:
3193             if (exit_on_mousedown) {
3194                 do_exit(cur_stream);
3195                 break;
3196             }
3197         case SDL_MOUSEMOTION:
3198             if (cursor_hidden) {
3199                 SDL_ShowCursor(1);
3200                 cursor_hidden = 0;
3201             }
3202             cursor_last_shown = av_gettime();
3203             if (event.type == SDL_MOUSEBUTTONDOWN) {
3204                 x = event.button.x;
3205             } else {
3206                 if (event.motion.state != SDL_PRESSED)
3207                     break;
3208                 x = event.motion.x;
3209             }
3210                 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3211                     uint64_t size =  avio_size(cur_stream->ic->pb);
3212                     stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3213                 } else {
3214                     int64_t ts;
3215                     int ns, hh, mm, ss;
3216                     int tns, thh, tmm, tss;
3217                     tns  = cur_stream->ic->duration / 1000000LL;
3218                     thh  = tns / 3600;
3219                     tmm  = (tns % 3600) / 60;
3220                     tss  = (tns % 60);
3221                     frac = x / cur_stream->width;
3222                     ns   = frac * tns;
3223                     hh   = ns / 3600;
3224                     mm   = (ns % 3600) / 60;
3225                     ss   = (ns % 60);
3226                     fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
3227                             hh, mm, ss, thh, tmm, tss);
3228                     ts = frac * cur_stream->ic->duration;
3229                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3230                         ts += cur_stream->ic->start_time;
3231                     stream_seek(cur_stream, ts, 0, 0);
3232                 }
3233             break;
3234         case SDL_VIDEORESIZE:
3235                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
3236                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
3237                 screen_width  = cur_stream->width  = event.resize.w;
3238                 screen_height = cur_stream->height = event.resize.h;
3239                 cur_stream->force_refresh = 1;
3240             break;
3241         case SDL_QUIT:
3242         case FF_QUIT_EVENT:
3243             do_exit(cur_stream);
3244             break;
3245         case FF_ALLOC_EVENT:
3246             alloc_picture(event.user.data1);
3247             break;
3248         default:
3249             break;
3250         }
3251     }
3252 }
3253
3254 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3255 {
3256     av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3257     return opt_default(NULL, "video_size", arg);
3258 }
3259
3260 static int opt_width(void *optctx, const char *opt, const char *arg)
3261 {
3262     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3263     return 0;
3264 }
3265
3266 static int opt_height(void *optctx, const char *opt, const char *arg)
3267 {
3268     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3269     return 0;
3270 }
3271
3272 static int opt_format(void *optctx, const char *opt, const char *arg)
3273 {
3274     file_iformat = av_find_input_format(arg);
3275     if (!file_iformat) {
3276         fprintf(stderr, "Unknown input format: %s\n", arg);
3277         return AVERROR(EINVAL);
3278     }
3279     return 0;
3280 }
3281
3282 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3283 {
3284     av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3285     return opt_default(NULL, "pixel_format", arg);
3286 }
3287
3288 static int opt_sync(void *optctx, const char *opt, const char *arg)
3289 {
3290     if (!strcmp(arg, "audio"))
3291         av_sync_type = AV_SYNC_AUDIO_MASTER;
3292     else if (!strcmp(arg, "video"))
3293         av_sync_type = AV_SYNC_VIDEO_MASTER;
3294     else if (!strcmp(arg, "ext"))
3295         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3296     else {
3297         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
3298         exit(1);
3299     }
3300     return 0;
3301 }
3302
3303 static int opt_seek(void *optctx, const char *opt, const char *arg)
3304 {
3305     start_time = parse_time_or_die(opt, arg, 1);
3306     return 0;
3307 }
3308
3309 static int opt_duration(void *optctx, const char *opt, const char *arg)
3310 {
3311     duration = parse_time_or_die(opt, arg, 1);
3312     return 0;
3313 }
3314
3315 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3316 {
3317     show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3318                 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3319                 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT  :
3320                 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3321     return 0;
3322 }
3323
3324 static void opt_input_file(void *optctx, const char *filename)
3325 {
3326     if (input_filename) {
3327         fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3328                 filename, input_filename);
3329         exit(1);
3330     }
3331     if (!strcmp(filename, "-"))
3332         filename = "pipe:";
3333     input_filename = filename;
3334 }
3335
3336 static int opt_codec(void *optctx, const char *opt, const char *arg)
3337 {
3338    const char *spec = strchr(opt, ':');
3339    if (!spec) {
3340        fprintf(stderr, "No media specifier was specified in '%s' in option '%s'\n",
3341                arg, opt);
3342        return AVERROR(EINVAL);
3343    }
3344    spec++;
3345    switch (spec[0]) {
3346    case 'a' :    audio_codec_name = arg; break;
3347    case 's' : subtitle_codec_name = arg; break;
3348    case 'v' :    video_codec_name = arg; break;
3349    default:
3350        fprintf(stderr, "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3351        return AVERROR(EINVAL);
3352    }
3353    return 0;
3354 }
3355
3356 static int dummy;
3357
3358 static const OptionDef options[] = {
3359 #include "cmdutils_common_opts.h"
3360     { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3361     { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3362     { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3363     { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3364     { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3365     { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3366     { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3367     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3368     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3369     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3370     { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3371     { "t", HAS_ARG, { .func_arg = opt_duration }, "play  \"duration\" seconds of audio/video", "duration" },
3372     { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3373     { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3374     { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3375     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3376     { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3377     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
3378     { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3379     { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3380     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3381     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3382     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { &idct }, "set idct algo",  "algo" },
3383     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options",  "bit_mask" },
3384     { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3385     { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3386     { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3387     { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3388     { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3389     { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3390     { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3391     { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3392 #if CONFIG_AVFILTER
3393     { "vf", OPT_STRING | HAS_ARG, { &vfilters }, "set video filters", "filter_graph" },
3394     { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3395 #endif
3396     { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3397     { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3398     { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3399     { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3400     { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3401     { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {    &audio_codec_name }, "force audio decoder",    "decoder_name" },
3402     { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3403     { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {    &video_codec_name }, "force video decoder",    "decoder_name" },
3404     { NULL, },
3405 };
3406
3407 static void show_usage(void)
3408 {
3409     av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3410     av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3411     av_log(NULL, AV_LOG_INFO, "\n");
3412 }
3413
3414 void show_help_default(const char *opt, const char *arg)
3415 {
3416     av_log_set_callback(log_callback_help);
3417     show_usage();
3418     show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3419     show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3420     printf("\n");
3421     show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3422     show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3423 #if !CONFIG_AVFILTER
3424     show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3425 #else
3426     show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3427 #endif
3428     printf("\nWhile playing:\n"
3429            "q, ESC              quit\n"
3430            "f                   toggle full screen\n"
3431            "p, SPC              pause\n"
3432            "a                   cycle audio channel\n"
3433            "v                   cycle video channel\n"
3434            "t                   cycle subtitle channel\n"
3435            "w                   show audio waves\n"
3436            "s                   activate frame-step mode\n"
3437            "left/right          seek backward/forward 10 seconds\n"
3438            "down/up             seek backward/forward 1 minute\n"
3439            "page down/page up   seek backward/forward 10 minutes\n"
3440            "mouse click         seek to percentage in file corresponding to fraction of width\n"
3441            );
3442 }
3443
3444 static int lockmgr(void **mtx, enum AVLockOp op)
3445 {
3446    switch(op) {
3447       case AV_LOCK_CREATE:
3448           *mtx = SDL_CreateMutex();
3449           if(!*mtx)
3450               return 1;
3451           return 0;
3452       case AV_LOCK_OBTAIN:
3453           return !!SDL_LockMutex(*mtx);
3454       case AV_LOCK_RELEASE:
3455           return !!SDL_UnlockMutex(*mtx);
3456       case AV_LOCK_DESTROY:
3457           SDL_DestroyMutex(*mtx);
3458           return 0;
3459    }
3460    return 1;
3461 }
3462
3463 /* Called from the main */
3464 int main(int argc, char **argv)
3465 {
3466     int flags;
3467     VideoState *is;
3468     char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3469
3470     av_log_set_flags(AV_LOG_SKIP_REPEATED);
3471     parse_loglevel(argc, argv, options);
3472
3473     /* register all codecs, demux and protocols */
3474     avcodec_register_all();
3475 #if CONFIG_AVDEVICE
3476     avdevice_register_all();
3477 #endif
3478 #if CONFIG_AVFILTER
3479     avfilter_register_all();
3480 #endif
3481     av_register_all();
3482     avformat_network_init();
3483
3484     init_opts();
3485
3486     signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
3487     signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
3488
3489     show_banner(argc, argv, options);
3490
3491     parse_options(NULL, argc, argv, options, opt_input_file);
3492
3493     if (!input_filename) {
3494         show_usage();
3495         fprintf(stderr, "An input file must be specified\n");
3496         fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3497         exit(1);
3498     }
3499
3500     if (display_disable) {
3501         video_disable = 1;
3502     }
3503     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3504     if (audio_disable)
3505         flags &= ~SDL_INIT_AUDIO;
3506     if (display_disable)
3507         SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3508 #if !defined(__MINGW32__) && !defined(__APPLE__)
3509     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3510 #endif
3511     if (SDL_Init (flags)) {
3512         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3513         fprintf(stderr, "(Did you set the DISPLAY variable?)\n");
3514         exit(1);
3515     }
3516
3517     if (!display_disable) {
3518         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3519         fs_screen_width = vi->current_w;
3520         fs_screen_height = vi->current_h;
3521     }
3522
3523     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3524     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3525     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3526
3527     if (av_lockmgr_register(lockmgr)) {
3528         fprintf(stderr, "Could not initialize lock manager!\n");
3529         do_exit(NULL);
3530     }
3531
3532     av_init_packet(&flush_pkt);
3533     flush_pkt.data = (char *)(intptr_t)"FLUSH";
3534
3535     is = stream_open(input_filename, file_iformat);
3536     if (!is) {
3537         fprintf(stderr, "Failed to initialize VideoState!\n");
3538         do_exit(NULL);
3539     }
3540
3541     event_loop(is);
3542
3543     /* never returns */
3544
3545     return 0;
3546 }