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