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