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