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