]> git.sesse.net Git - ffmpeg/blob - ffplay.c
Merge remote-tracking branch 'qatar/master'
[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         pic->base[i]     = ref->data[i];
1586         if (ref->data[i]) {
1587             ref->data[i]    += ((edge * pixel_size) >> hshift) + ((edge * ref->linesize[i]) >> vshift);
1588         }
1589         pic->data[i]     = ref->data[i];
1590         pic->linesize[i] = ref->linesize[i];
1591     }
1592     pic->opaque = ref;
1593     pic->type   = FF_BUFFER_TYPE_USER;
1594     pic->reordered_opaque = codec->reordered_opaque;
1595     pic->width               = codec->width;
1596     pic->height              = codec->height;
1597     pic->format              = codec->pix_fmt;
1598     pic->sample_aspect_ratio = codec->sample_aspect_ratio;
1599     if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
1600     else            pic->pkt_pts = AV_NOPTS_VALUE;
1601     return 0;
1602 }
1603
1604 static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
1605 {
1606     memset(pic->data, 0, sizeof(pic->data));
1607     avfilter_unref_buffer(pic->opaque);
1608 }
1609
1610 static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
1611 {
1612     AVFilterBufferRef *ref = pic->opaque;
1613
1614     if (pic->data[0] == NULL) {
1615         pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
1616         return codec->get_buffer(codec, pic);
1617     }
1618
1619     if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
1620         (codec->pix_fmt != ref->format)) {
1621         av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
1622         return -1;
1623     }
1624
1625     pic->reordered_opaque = codec->reordered_opaque;
1626     if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
1627     else            pic->pkt_pts = AV_NOPTS_VALUE;
1628     return 0;
1629 }
1630
1631 static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
1632 {
1633     FilterPriv *priv = ctx->priv;
1634     AVCodecContext *codec;
1635     if (!opaque) return -1;
1636
1637     priv->is = opaque;
1638     codec    = priv->is->video_st->codec;
1639     codec->opaque = ctx;
1640     if (codec->codec->capabilities & CODEC_CAP_DR1) {
1641         av_assert0(codec->flags & CODEC_FLAG_EMU_EDGE);
1642         priv->use_dr1 = 1;
1643         codec->get_buffer     = input_get_buffer;
1644         codec->release_buffer = input_release_buffer;
1645         codec->reget_buffer   = input_reget_buffer;
1646         codec->thread_safe_callbacks = 1;
1647     }
1648
1649     priv->frame = avcodec_alloc_frame();
1650
1651     return 0;
1652 }
1653
1654 static void input_uninit(AVFilterContext *ctx)
1655 {
1656     FilterPriv *priv = ctx->priv;
1657     av_free(priv->frame);
1658 }
1659
1660 static int input_request_frame(AVFilterLink *link)
1661 {
1662     FilterPriv *priv = link->src->priv;
1663     AVFilterBufferRef *picref;
1664     int64_t pts = 0;
1665     AVPacket pkt;
1666     int ret;
1667
1668     while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
1669         av_free_packet(&pkt);
1670     if (ret < 0)
1671         return -1;
1672
1673     if (priv->use_dr1 && priv->frame->opaque) {
1674         picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
1675     } else {
1676         picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, priv->frame->width, priv->frame->height);
1677         av_image_copy(picref->data, picref->linesize,
1678                       (const uint8_t **)(void **)priv->frame->data, priv->frame->linesize,
1679                       picref->format, priv->frame->width, priv->frame->height);
1680     }
1681     av_free_packet(&pkt);
1682
1683     avfilter_copy_frame_props(picref, priv->frame);
1684     picref->video->sample_aspect_ratio = av_guess_sample_aspect_ratio(priv->is->ic, priv->is->video_st, priv->frame);
1685     picref->pts = pts;
1686
1687     avfilter_start_frame(link, picref);
1688     avfilter_draw_slice(link, 0, picref->video->h, 1);
1689     avfilter_end_frame(link);
1690
1691     return 0;
1692 }
1693
1694 static int input_query_formats(AVFilterContext *ctx)
1695 {
1696     FilterPriv *priv = ctx->priv;
1697     enum PixelFormat pix_fmts[] = {
1698         priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
1699     };
1700
1701     avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
1702     return 0;
1703 }
1704
1705 static int input_config_props(AVFilterLink *link)
1706 {
1707     FilterPriv *priv  = link->src->priv;
1708     AVStream *s = priv->is->video_st;
1709
1710     link->w = s->codec->width;
1711     link->h = s->codec->height;
1712     link->sample_aspect_ratio = s->sample_aspect_ratio.num ?
1713         s->sample_aspect_ratio : s->codec->sample_aspect_ratio;
1714     link->time_base = s->time_base;
1715
1716     return 0;
1717 }
1718
1719 static AVFilter input_filter =
1720 {
1721     .name      = "ffplay_input",
1722
1723     .priv_size = sizeof(FilterPriv),
1724
1725     .init      = input_init,
1726     .uninit    = input_uninit,
1727
1728     .query_formats = input_query_formats,
1729
1730     .inputs    = (AVFilterPad[]) {{ .name = NULL }},
1731     .outputs   = (AVFilterPad[]) {{ .name = "default",
1732                                     .type = AVMEDIA_TYPE_VIDEO,
1733                                     .request_frame = input_request_frame,
1734                                     .config_props  = input_config_props, },
1735                                   { .name = NULL }},
1736 };
1737
1738 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
1739 {
1740     static const enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
1741     char sws_flags_str[128];
1742     int ret;
1743     AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
1744     AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_format;;
1745     snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
1746     graph->scale_sws_opts = av_strdup(sws_flags_str);
1747
1748     if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
1749                                             NULL, is, graph)) < 0)
1750         return ret;
1751
1752 #if FF_API_OLD_VSINK_API
1753     ret = avfilter_graph_create_filter(&filt_out,
1754                                        avfilter_get_by_name("buffersink"),
1755                                        "out", NULL, pix_fmts, graph);
1756 #else
1757     buffersink_params->pixel_fmts = pix_fmts;
1758     ret = avfilter_graph_create_filter(&filt_out,
1759                                        avfilter_get_by_name("buffersink"),
1760                                        "out", NULL, buffersink_params, graph);
1761 #endif
1762     av_freep(&buffersink_params);
1763     if (ret < 0)
1764         return ret;
1765
1766     if ((ret = avfilter_graph_create_filter(&filt_format,
1767                                             avfilter_get_by_name("format"),
1768                                             "format", "yuv420p", NULL, graph)) < 0)
1769         return ret;
1770     if ((ret = avfilter_link(filt_format, 0, filt_out, 0)) < 0)
1771         return ret;
1772
1773
1774     if (vfilters) {
1775         AVFilterInOut *outputs = avfilter_inout_alloc();
1776         AVFilterInOut *inputs  = avfilter_inout_alloc();
1777
1778         outputs->name    = av_strdup("in");
1779         outputs->filter_ctx = filt_src;
1780         outputs->pad_idx = 0;
1781         outputs->next    = NULL;
1782
1783         inputs->name    = av_strdup("out");
1784         inputs->filter_ctx = filt_format;
1785         inputs->pad_idx = 0;
1786         inputs->next    = NULL;
1787
1788         if ((ret = avfilter_graph_parse(graph, vfilters, &inputs, &outputs, NULL)) < 0)
1789             return ret;
1790     } else {
1791         if ((ret = avfilter_link(filt_src, 0, filt_format, 0)) < 0)
1792             return ret;
1793     }
1794
1795     if ((ret = avfilter_graph_config(graph, NULL)) < 0)
1796         return ret;
1797
1798     is->out_video_filter = filt_out;
1799
1800     return ret;
1801 }
1802
1803 #endif  /* CONFIG_AVFILTER */
1804
1805 static int video_thread(void *arg)
1806 {
1807     VideoState *is = arg;
1808     AVFrame *frame = avcodec_alloc_frame();
1809     int64_t pts_int = AV_NOPTS_VALUE, pos = -1;
1810     double pts;
1811     int ret;
1812
1813 #if CONFIG_AVFILTER
1814     AVFilterGraph *graph = avfilter_graph_alloc();
1815     AVFilterContext *filt_out = NULL;
1816     int last_w = is->video_st->codec->width;
1817     int last_h = is->video_st->codec->height;
1818
1819     if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1820         goto the_end;
1821     filt_out = is->out_video_filter;
1822 #endif
1823
1824     for (;;) {
1825 #if !CONFIG_AVFILTER
1826         AVPacket pkt;
1827 #else
1828         AVFilterBufferRef *picref;
1829         AVRational tb = filt_out->inputs[0]->time_base;
1830 #endif
1831         while (is->paused && !is->videoq.abort_request)
1832             SDL_Delay(10);
1833 #if CONFIG_AVFILTER
1834         if (   last_w != is->video_st->codec->width
1835             || last_h != is->video_st->codec->height) {
1836             av_log(NULL, AV_LOG_INFO, "Frame changed from size:%dx%d to size:%dx%d\n",
1837                    last_w, last_h, is->video_st->codec->width, is->video_st->codec->height);
1838             avfilter_graph_free(&graph);
1839             graph = avfilter_graph_alloc();
1840             if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1841                 goto the_end;
1842             filt_out = is->out_video_filter;
1843             last_w = is->video_st->codec->width;
1844             last_h = is->video_st->codec->height;
1845         }
1846         ret = av_buffersink_get_buffer_ref(filt_out, &picref, 0);
1847         if (picref) {
1848             avfilter_fill_frame_from_video_buffer_ref(frame, picref);
1849             pts_int = picref->pts;
1850             tb      = filt_out->inputs[0]->time_base;
1851             pos     = picref->pos;
1852             frame->opaque = picref;
1853
1854             ret = 1;
1855         }
1856
1857         if (ret >= 0 && av_cmp_q(tb, is->video_st->time_base)) {
1858             av_unused int64_t pts1 = pts_int;
1859             pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
1860             av_dlog(NULL, "video_thread(): "
1861                     "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
1862                     tb.num, tb.den, pts1,
1863                     is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
1864         }
1865 #else
1866         ret = get_video_frame(is, frame, &pts_int, &pkt);
1867         pos = pkt.pos;
1868         av_free_packet(&pkt);
1869         if (ret == 0)
1870             continue;
1871 #endif
1872
1873         if (ret < 0)
1874             goto the_end;
1875
1876         is->frame_last_filter_delay = av_gettime() / 1000000.0 - is->frame_last_returned_time;
1877         if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
1878             is->frame_last_filter_delay = 0;
1879
1880 #if CONFIG_AVFILTER
1881         if (!picref)
1882             continue;
1883 #endif
1884
1885         pts = pts_int * av_q2d(is->video_st->time_base);
1886
1887         ret = queue_picture(is, frame, pts, pos);
1888
1889         if (ret < 0)
1890             goto the_end;
1891
1892         if (is->step)
1893             stream_toggle_pause(is);
1894     }
1895  the_end:
1896 #if CONFIG_AVFILTER
1897     av_freep(&vfilters);
1898     avfilter_graph_free(&graph);
1899 #endif
1900     av_free(frame);
1901     return 0;
1902 }
1903
1904 static int subtitle_thread(void *arg)
1905 {
1906     VideoState *is = arg;
1907     SubPicture *sp;
1908     AVPacket pkt1, *pkt = &pkt1;
1909     int got_subtitle;
1910     double pts;
1911     int i, j;
1912     int r, g, b, y, u, v, a;
1913
1914     for (;;) {
1915         while (is->paused && !is->subtitleq.abort_request) {
1916             SDL_Delay(10);
1917         }
1918         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1919             break;
1920
1921         if (pkt->data == flush_pkt.data) {
1922             avcodec_flush_buffers(is->subtitle_st->codec);
1923             continue;
1924         }
1925         SDL_LockMutex(is->subpq_mutex);
1926         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1927                !is->subtitleq.abort_request) {
1928             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1929         }
1930         SDL_UnlockMutex(is->subpq_mutex);
1931
1932         if (is->subtitleq.abort_request)
1933             return 0;
1934
1935         sp = &is->subpq[is->subpq_windex];
1936
1937        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1938            this packet, if any */
1939         pts = 0;
1940         if (pkt->pts != AV_NOPTS_VALUE)
1941             pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
1942
1943         avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
1944                                  &got_subtitle, pkt);
1945
1946         if (got_subtitle && sp->sub.format == 0) {
1947             sp->pts = pts;
1948
1949             for (i = 0; i < sp->sub.num_rects; i++)
1950             {
1951                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1952                 {
1953                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1954                     y = RGB_TO_Y_CCIR(r, g, b);
1955                     u = RGB_TO_U_CCIR(r, g, b, 0);
1956                     v = RGB_TO_V_CCIR(r, g, b, 0);
1957                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1958                 }
1959             }
1960
1961             /* now we can update the picture count */
1962             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1963                 is->subpq_windex = 0;
1964             SDL_LockMutex(is->subpq_mutex);
1965             is->subpq_size++;
1966             SDL_UnlockMutex(is->subpq_mutex);
1967         }
1968         av_free_packet(pkt);
1969     }
1970     return 0;
1971 }
1972
1973 /* copy samples for viewing in editor window */
1974 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1975 {
1976     int size, len;
1977
1978     size = samples_size / sizeof(short);
1979     while (size > 0) {
1980         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1981         if (len > size)
1982             len = size;
1983         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1984         samples += len;
1985         is->sample_array_index += len;
1986         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1987             is->sample_array_index = 0;
1988         size -= len;
1989     }
1990 }
1991
1992 /* return the wanted number of samples to get better sync if sync_type is video
1993  * or external master clock */
1994 static int synchronize_audio(VideoState *is, int nb_samples)
1995 {
1996     int wanted_nb_samples = nb_samples;
1997
1998     /* if not master, then we try to remove or add samples to correct the clock */
1999     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
2000          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
2001         double diff, avg_diff;
2002         int min_nb_samples, max_nb_samples;
2003
2004         diff = get_audio_clock(is) - get_master_clock(is);
2005
2006         if (diff < AV_NOSYNC_THRESHOLD) {
2007             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2008             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2009                 /* not enough measures to have a correct estimate */
2010                 is->audio_diff_avg_count++;
2011             } else {
2012                 /* estimate the A-V difference */
2013                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2014
2015                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2016                     wanted_nb_samples = nb_samples + (int)(diff * is->audio_src_freq);
2017                     min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2018                     max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2019                     wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2020                 }
2021                 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
2022                         diff, avg_diff, wanted_nb_samples - nb_samples,
2023                         is->audio_clock, is->video_clock, is->audio_diff_threshold);
2024             }
2025         } else {
2026             /* too big difference : may be initial PTS errors, so
2027                reset A-V filter */
2028             is->audio_diff_avg_count = 0;
2029             is->audio_diff_cum       = 0;
2030         }
2031     }
2032
2033     return wanted_nb_samples;
2034 }
2035
2036 /* decode one audio frame and returns its uncompressed size */
2037 static int audio_decode_frame(VideoState *is, double *pts_ptr)
2038 {
2039     AVPacket *pkt_temp = &is->audio_pkt_temp;
2040     AVPacket *pkt = &is->audio_pkt;
2041     AVCodecContext *dec = is->audio_st->codec;
2042     int len1, len2, data_size, resampled_data_size;
2043     int64_t dec_channel_layout;
2044     int got_frame;
2045     double pts;
2046     int new_packet = 0;
2047     int flush_complete = 0;
2048     int wanted_nb_samples;
2049
2050     for (;;) {
2051         /* NOTE: the audio packet can contain several frames */
2052         while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
2053             if (!is->frame) {
2054                 if (!(is->frame = avcodec_alloc_frame()))
2055                     return AVERROR(ENOMEM);
2056             } else
2057                 avcodec_get_frame_defaults(is->frame);
2058
2059             if (flush_complete)
2060                 break;
2061             new_packet = 0;
2062             len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2063             if (len1 < 0) {
2064                 /* if error, we skip the frame */
2065                 pkt_temp->size = 0;
2066                 break;
2067             }
2068
2069             pkt_temp->data += len1;
2070             pkt_temp->size -= len1;
2071
2072             if (!got_frame) {
2073                 /* stop sending empty packets if the decoder is finished */
2074                 if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
2075                     flush_complete = 1;
2076                 continue;
2077             }
2078             data_size = av_samples_get_buffer_size(NULL, dec->channels,
2079                                                    is->frame->nb_samples,
2080                                                    dec->sample_fmt, 1);
2081
2082             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);
2083             wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2084
2085             if (dec->sample_fmt != is->audio_src_fmt ||
2086                 dec_channel_layout != is->audio_src_channel_layout ||
2087                 dec->sample_rate != is->audio_src_freq ||
2088                 (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2089                 if (is->swr_ctx)
2090                     swr_free(&is->swr_ctx);
2091                 is->swr_ctx = swr_alloc_set_opts(NULL,
2092                                                  is->audio_tgt_channel_layout, is->audio_tgt_fmt, is->audio_tgt_freq,
2093                                                  dec_channel_layout,           dec->sample_fmt,   dec->sample_rate,
2094                                                  0, NULL);
2095                 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2096                     fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2097                         dec->sample_rate,
2098                         av_get_sample_fmt_name(dec->sample_fmt),
2099                         dec->channels,
2100                         is->audio_tgt_freq,
2101                         av_get_sample_fmt_name(is->audio_tgt_fmt),
2102                         is->audio_tgt_channels);
2103                     break;
2104                 }
2105                 is->audio_src_channel_layout = dec_channel_layout;
2106                 is->audio_src_channels = dec->channels;
2107                 is->audio_src_freq = dec->sample_rate;
2108                 is->audio_src_fmt = dec->sample_fmt;
2109             }
2110
2111             resampled_data_size = data_size;
2112             if (is->swr_ctx) {
2113                 const uint8_t *in[] = { is->frame->data[0] };
2114                 uint8_t *out[] = {is->audio_buf2};
2115                 if (wanted_nb_samples != is->frame->nb_samples) {
2116                     if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt_freq / dec->sample_rate,
2117                                                 wanted_nb_samples * is->audio_tgt_freq / dec->sample_rate) < 0) {
2118                         fprintf(stderr, "swr_set_compensation() failed\n");
2119                         break;
2120                     }
2121                 }
2122                 len2 = swr_convert(is->swr_ctx, out, sizeof(is->audio_buf2) / is->audio_tgt_channels / av_get_bytes_per_sample(is->audio_tgt_fmt),
2123                                                 in, is->frame->nb_samples);
2124                 if (len2 < 0) {
2125                     fprintf(stderr, "audio_resample() failed\n");
2126                     break;
2127                 }
2128                 if (len2 == sizeof(is->audio_buf2) / is->audio_tgt_channels / av_get_bytes_per_sample(is->audio_tgt_fmt)) {
2129                     fprintf(stderr, "warning: audio buffer is probably too small\n");
2130                     swr_init(is->swr_ctx);
2131                 }
2132                 is->audio_buf = is->audio_buf2;
2133                 resampled_data_size = len2 * is->audio_tgt_channels * av_get_bytes_per_sample(is->audio_tgt_fmt);
2134             } else {
2135                 is->audio_buf = is->frame->data[0];
2136             }
2137
2138             /* if no pts, then compute it */
2139             pts = is->audio_clock;
2140             *pts_ptr = pts;
2141             is->audio_clock += (double)data_size /
2142                 (dec->channels * dec->sample_rate * av_get_bytes_per_sample(dec->sample_fmt));
2143 #ifdef DEBUG
2144             {
2145                 static double last_clock;
2146                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
2147                        is->audio_clock - last_clock,
2148                        is->audio_clock, pts);
2149                 last_clock = is->audio_clock;
2150             }
2151 #endif
2152             return resampled_data_size;
2153         }
2154
2155         /* free the current packet */
2156         if (pkt->data)
2157             av_free_packet(pkt);
2158         memset(pkt_temp, 0, sizeof(*pkt_temp));
2159
2160         if (is->paused || is->audioq.abort_request) {
2161             return -1;
2162         }
2163
2164         /* read next packet */
2165         if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
2166             return -1;
2167
2168         if (pkt->data == flush_pkt.data) {
2169             avcodec_flush_buffers(dec);
2170             flush_complete = 0;
2171         }
2172
2173         *pkt_temp = *pkt;
2174
2175         /* if update the audio clock with the pts */
2176         if (pkt->pts != AV_NOPTS_VALUE) {
2177             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
2178         }
2179     }
2180 }
2181
2182 /* prepare a new audio buffer */
2183 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2184 {
2185     VideoState *is = opaque;
2186     int audio_size, len1;
2187     int bytes_per_sec;
2188     int frame_size = av_samples_get_buffer_size(NULL, is->audio_tgt_channels, 1, is->audio_tgt_fmt, 1);
2189     double pts;
2190
2191     audio_callback_time = av_gettime();
2192
2193     while (len > 0) {
2194         if (is->audio_buf_index >= is->audio_buf_size) {
2195            audio_size = audio_decode_frame(is, &pts);
2196            if (audio_size < 0) {
2197                 /* if error, just output silence */
2198                is->audio_buf      = is->silence_buf;
2199                is->audio_buf_size = sizeof(is->silence_buf) / frame_size * frame_size;
2200            } else {
2201                if (is->show_mode != SHOW_MODE_VIDEO)
2202                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2203                is->audio_buf_size = audio_size;
2204            }
2205            is->audio_buf_index = 0;
2206         }
2207         len1 = is->audio_buf_size - is->audio_buf_index;
2208         if (len1 > len)
2209             len1 = len;
2210         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2211         len -= len1;
2212         stream += len1;
2213         is->audio_buf_index += len1;
2214     }
2215     bytes_per_sec = is->audio_tgt_freq * is->audio_tgt_channels * av_get_bytes_per_sample(is->audio_tgt_fmt);
2216     is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2217     /* Let's assume the audio driver that is used by SDL has two periods. */
2218     is->audio_current_pts = is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec;
2219     is->audio_current_pts_drift = is->audio_current_pts - audio_callback_time / 1000000.0;
2220 }
2221
2222 /* open a given stream. Return 0 if OK */
2223 static int stream_component_open(VideoState *is, int stream_index)
2224 {
2225     AVFormatContext *ic = is->ic;
2226     AVCodecContext *avctx;
2227     AVCodec *codec;
2228     SDL_AudioSpec wanted_spec, spec;
2229     AVDictionary *opts;
2230     AVDictionaryEntry *t = NULL;
2231     int64_t wanted_channel_layout = 0;
2232     int wanted_nb_channels;
2233     const char *env;
2234
2235     if (stream_index < 0 || stream_index >= ic->nb_streams)
2236         return -1;
2237     avctx = ic->streams[stream_index]->codec;
2238
2239     codec = avcodec_find_decoder(avctx->codec_id);
2240     opts = filter_codec_opts(codec_opts, codec, ic, ic->streams[stream_index]);
2241
2242     switch(avctx->codec_type){
2243         case AVMEDIA_TYPE_AUDIO   : if(audio_codec_name   ) codec= avcodec_find_decoder_by_name(   audio_codec_name); break;
2244         case AVMEDIA_TYPE_SUBTITLE: if(subtitle_codec_name) codec= avcodec_find_decoder_by_name(subtitle_codec_name); break;
2245         case AVMEDIA_TYPE_VIDEO   : if(video_codec_name   ) codec= avcodec_find_decoder_by_name(   video_codec_name); break;
2246     }
2247     if (!codec)
2248         return -1;
2249
2250     avctx->workaround_bugs   = workaround_bugs;
2251     avctx->lowres            = lowres;
2252     if(avctx->lowres > codec->max_lowres){
2253         av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2254                 codec->max_lowres);
2255         avctx->lowres= codec->max_lowres;
2256     }
2257     avctx->idct_algo         = idct;
2258     avctx->skip_frame        = skip_frame;
2259     avctx->skip_idct         = skip_idct;
2260     avctx->skip_loop_filter  = skip_loop_filter;
2261     avctx->error_concealment = error_concealment;
2262
2263     if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2264     if (fast)   avctx->flags2 |= CODEC_FLAG2_FAST;
2265     if(codec->capabilities & CODEC_CAP_DR1)
2266         avctx->flags |= CODEC_FLAG_EMU_EDGE;
2267
2268     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2269         memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
2270         env = SDL_getenv("SDL_AUDIO_CHANNELS");
2271         if (env)
2272             wanted_channel_layout = av_get_default_channel_layout(SDL_atoi(env));
2273         if (!wanted_channel_layout) {
2274             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);
2275             wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2276             wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2277             /* SDL only supports 1, 2, 4 or 6 channels at the moment, so we have to make sure not to request anything else. */
2278             while (wanted_nb_channels > 0 && (wanted_nb_channels == 3 || wanted_nb_channels == 5 || wanted_nb_channels > 6)) {
2279                 wanted_nb_channels--;
2280                 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2281             }
2282         }
2283         wanted_spec.channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2284         wanted_spec.freq = avctx->sample_rate;
2285         if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2286             fprintf(stderr, "Invalid sample rate or channel count!\n");
2287             return -1;
2288         }
2289     }
2290
2291     if (!av_dict_get(opts, "threads", NULL, 0))
2292         av_dict_set(&opts, "threads", "auto", 0);
2293     if (!codec ||
2294         avcodec_open2(avctx, codec, &opts) < 0)
2295         return -1;
2296     if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2297         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2298         return AVERROR_OPTION_NOT_FOUND;
2299     }
2300
2301     /* prepare audio output */
2302     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2303         wanted_spec.format = AUDIO_S16SYS;
2304         wanted_spec.silence = 0;
2305         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2306         wanted_spec.callback = sdl_audio_callback;
2307         wanted_spec.userdata = is;
2308         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2309             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
2310             return -1;
2311         }
2312         is->audio_hw_buf_size = spec.size;
2313         if (spec.format != AUDIO_S16SYS) {
2314             fprintf(stderr, "SDL advised audio format %d is not supported!\n", spec.format);
2315             return -1;
2316         }
2317         if (spec.channels != wanted_spec.channels) {
2318             wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2319             if (!wanted_channel_layout) {
2320                 fprintf(stderr, "SDL advised channel count %d is not supported!\n", spec.channels);
2321                 return -1;
2322             }
2323         }
2324         is->audio_src_fmt = is->audio_tgt_fmt = AV_SAMPLE_FMT_S16;
2325         is->audio_src_freq = is->audio_tgt_freq = spec.freq;
2326         is->audio_src_channel_layout = is->audio_tgt_channel_layout = wanted_channel_layout;
2327         is->audio_src_channels = is->audio_tgt_channels = spec.channels;
2328     }
2329
2330     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2331     switch (avctx->codec_type) {
2332     case AVMEDIA_TYPE_AUDIO:
2333         is->audio_stream = stream_index;
2334         is->audio_st = ic->streams[stream_index];
2335         is->audio_buf_size  = 0;
2336         is->audio_buf_index = 0;
2337
2338         /* init averaging filter */
2339         is->audio_diff_avg_coef  = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2340         is->audio_diff_avg_count = 0;
2341         /* since we do not have a precise anough audio fifo fullness,
2342            we correct audio sync only if larger than this threshold */
2343         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / wanted_spec.freq;
2344
2345         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2346         packet_queue_init(&is->audioq);
2347         SDL_PauseAudio(0);
2348         break;
2349     case AVMEDIA_TYPE_VIDEO:
2350         is->video_stream = stream_index;
2351         is->video_st = ic->streams[stream_index];
2352
2353         packet_queue_init(&is->videoq);
2354         is->video_tid = SDL_CreateThread(video_thread, is);
2355         break;
2356     case AVMEDIA_TYPE_SUBTITLE:
2357         is->subtitle_stream = stream_index;
2358         is->subtitle_st = ic->streams[stream_index];
2359         packet_queue_init(&is->subtitleq);
2360
2361         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2362         break;
2363     default:
2364         break;
2365     }
2366     return 0;
2367 }
2368
2369 static void stream_component_close(VideoState *is, int stream_index)
2370 {
2371     AVFormatContext *ic = is->ic;
2372     AVCodecContext *avctx;
2373
2374     if (stream_index < 0 || stream_index >= ic->nb_streams)
2375         return;
2376     avctx = ic->streams[stream_index]->codec;
2377
2378     switch (avctx->codec_type) {
2379     case AVMEDIA_TYPE_AUDIO:
2380         packet_queue_abort(&is->audioq);
2381
2382         SDL_CloseAudio();
2383
2384         packet_queue_end(&is->audioq);
2385         av_free_packet(&is->audio_pkt);
2386         if (is->swr_ctx)
2387             swr_free(&is->swr_ctx);
2388         av_freep(&is->audio_buf1);
2389         is->audio_buf = NULL;
2390         av_freep(&is->frame);
2391
2392         if (is->rdft) {
2393             av_rdft_end(is->rdft);
2394             av_freep(&is->rdft_data);
2395             is->rdft = NULL;
2396             is->rdft_bits = 0;
2397         }
2398         break;
2399     case AVMEDIA_TYPE_VIDEO:
2400         packet_queue_abort(&is->videoq);
2401
2402         /* note: we also signal this mutex to make sure we deblock the
2403            video thread in all cases */
2404         SDL_LockMutex(is->pictq_mutex);
2405         SDL_CondSignal(is->pictq_cond);
2406         SDL_UnlockMutex(is->pictq_mutex);
2407
2408         SDL_WaitThread(is->video_tid, NULL);
2409
2410         packet_queue_end(&is->videoq);
2411         break;
2412     case AVMEDIA_TYPE_SUBTITLE:
2413         packet_queue_abort(&is->subtitleq);
2414
2415         /* note: we also signal this mutex to make sure we deblock the
2416            video thread in all cases */
2417         SDL_LockMutex(is->subpq_mutex);
2418         is->subtitle_stream_changed = 1;
2419
2420         SDL_CondSignal(is->subpq_cond);
2421         SDL_UnlockMutex(is->subpq_mutex);
2422
2423         SDL_WaitThread(is->subtitle_tid, NULL);
2424
2425         packet_queue_end(&is->subtitleq);
2426         break;
2427     default:
2428         break;
2429     }
2430
2431     ic->streams[stream_index]->discard = AVDISCARD_ALL;
2432     avcodec_close(avctx);
2433     switch (avctx->codec_type) {
2434     case AVMEDIA_TYPE_AUDIO:
2435         is->audio_st = NULL;
2436         is->audio_stream = -1;
2437         break;
2438     case AVMEDIA_TYPE_VIDEO:
2439         is->video_st = NULL;
2440         is->video_stream = -1;
2441         break;
2442     case AVMEDIA_TYPE_SUBTITLE:
2443         is->subtitle_st = NULL;
2444         is->subtitle_stream = -1;
2445         break;
2446     default:
2447         break;
2448     }
2449 }
2450
2451 static int decode_interrupt_cb(void *ctx)
2452 {
2453     VideoState *is = ctx;
2454     return is->abort_request;
2455 }
2456
2457 /* this thread gets the stream from the disk or the network */
2458 static int read_thread(void *arg)
2459 {
2460     VideoState *is = arg;
2461     AVFormatContext *ic = NULL;
2462     int err, i, ret;
2463     int st_index[AVMEDIA_TYPE_NB];
2464     AVPacket pkt1, *pkt = &pkt1;
2465     int eof = 0;
2466     int pkt_in_play_range = 0;
2467     AVDictionaryEntry *t;
2468     AVDictionary **opts;
2469     int orig_nb_streams;
2470
2471     memset(st_index, -1, sizeof(st_index));
2472     is->video_stream = -1;
2473     is->audio_stream = -1;
2474     is->subtitle_stream = -1;
2475
2476     ic = avformat_alloc_context();
2477     ic->interrupt_callback.callback = decode_interrupt_cb;
2478     ic->interrupt_callback.opaque = is;
2479     err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2480     if (err < 0) {
2481         print_error(is->filename, err);
2482         ret = -1;
2483         goto fail;
2484     }
2485     if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2486         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2487         ret = AVERROR_OPTION_NOT_FOUND;
2488         goto fail;
2489     }
2490     is->ic = ic;
2491
2492     if (genpts)
2493         ic->flags |= AVFMT_FLAG_GENPTS;
2494
2495     opts = setup_find_stream_info_opts(ic, codec_opts);
2496     orig_nb_streams = ic->nb_streams;
2497
2498     err = avformat_find_stream_info(ic, opts);
2499     if (err < 0) {
2500         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2501         ret = -1;
2502         goto fail;
2503     }
2504     for (i = 0; i < orig_nb_streams; i++)
2505         av_dict_free(&opts[i]);
2506     av_freep(&opts);
2507
2508     if (ic->pb)
2509         ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
2510
2511     if (seek_by_bytes < 0)
2512         seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT);
2513
2514     /* if seeking requested, we execute it */
2515     if (start_time != AV_NOPTS_VALUE) {
2516         int64_t timestamp;
2517
2518         timestamp = start_time;
2519         /* add the stream start time */
2520         if (ic->start_time != AV_NOPTS_VALUE)
2521             timestamp += ic->start_time;
2522         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2523         if (ret < 0) {
2524             fprintf(stderr, "%s: could not seek to position %0.3f\n",
2525                     is->filename, (double)timestamp / AV_TIME_BASE);
2526         }
2527     }
2528
2529     for (i = 0; i < ic->nb_streams; i++)
2530         ic->streams[i]->discard = AVDISCARD_ALL;
2531     if (!video_disable)
2532         st_index[AVMEDIA_TYPE_VIDEO] =
2533             av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2534                                 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2535     if (!audio_disable)
2536         st_index[AVMEDIA_TYPE_AUDIO] =
2537             av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2538                                 wanted_stream[AVMEDIA_TYPE_AUDIO],
2539                                 st_index[AVMEDIA_TYPE_VIDEO],
2540                                 NULL, 0);
2541     if (!video_disable)
2542         st_index[AVMEDIA_TYPE_SUBTITLE] =
2543             av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2544                                 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2545                                 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2546                                  st_index[AVMEDIA_TYPE_AUDIO] :
2547                                  st_index[AVMEDIA_TYPE_VIDEO]),
2548                                 NULL, 0);
2549     if (show_status) {
2550         av_dump_format(ic, 0, is->filename, 0);
2551     }
2552
2553     is->show_mode = show_mode;
2554
2555     /* open the streams */
2556     if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2557         stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2558     }
2559
2560     ret = -1;
2561     if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2562         ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2563     }
2564     is->refresh_tid = SDL_CreateThread(refresh_thread, is);
2565     if (is->show_mode == SHOW_MODE_NONE)
2566         is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2567
2568     if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2569         stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2570     }
2571
2572     if (is->video_stream < 0 && is->audio_stream < 0) {
2573         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2574         ret = -1;
2575         goto fail;
2576     }
2577
2578     for (;;) {
2579         if (is->abort_request)
2580             break;
2581         if (is->paused != is->last_paused) {
2582             is->last_paused = is->paused;
2583             if (is->paused)
2584                 is->read_pause_return = av_read_pause(ic);
2585             else
2586                 av_read_play(ic);
2587         }
2588 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2589         if (is->paused &&
2590                 (!strcmp(ic->iformat->name, "rtsp") ||
2591                  (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2592             /* wait 10 ms to avoid trying to get another packet */
2593             /* XXX: horrible */
2594             SDL_Delay(10);
2595             continue;
2596         }
2597 #endif
2598         if (is->seek_req) {
2599             int64_t seek_target = is->seek_pos;
2600             int64_t seek_min    = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2601             int64_t seek_max    = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2602 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2603 //      of the seek_pos/seek_rel variables
2604
2605             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2606             if (ret < 0) {
2607                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2608             } else {
2609                 if (is->audio_stream >= 0) {
2610                     packet_queue_flush(&is->audioq);
2611                     packet_queue_put(&is->audioq, &flush_pkt);
2612                 }
2613                 if (is->subtitle_stream >= 0) {
2614                     packet_queue_flush(&is->subtitleq);
2615                     packet_queue_put(&is->subtitleq, &flush_pkt);
2616                 }
2617                 if (is->video_stream >= 0) {
2618                     packet_queue_flush(&is->videoq);
2619                     packet_queue_put(&is->videoq, &flush_pkt);
2620                 }
2621             }
2622             is->seek_req = 0;
2623             eof = 0;
2624         }
2625
2626         /* if the queue are full, no need to read more */
2627         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2628             || (   (is->audioq   .nb_packets > MIN_FRAMES || is->audio_stream < 0)
2629                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream < 0)
2630                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0))) {
2631             /* wait 10 ms */
2632             SDL_Delay(10);
2633             continue;
2634         }
2635         if (eof) {
2636             if (is->video_stream >= 0) {
2637                 av_init_packet(pkt);
2638                 pkt->data = NULL;
2639                 pkt->size = 0;
2640                 pkt->stream_index = is->video_stream;
2641                 packet_queue_put(&is->videoq, pkt);
2642             }
2643             if (is->audio_stream >= 0 &&
2644                 is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
2645                 av_init_packet(pkt);
2646                 pkt->data = NULL;
2647                 pkt->size = 0;
2648                 pkt->stream_index = is->audio_stream;
2649                 packet_queue_put(&is->audioq, pkt);
2650             }
2651             SDL_Delay(10);
2652             if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
2653                 if (loop != 1 && (!loop || --loop)) {
2654                     stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2655                 } else if (autoexit) {
2656                     ret = AVERROR_EOF;
2657                     goto fail;
2658                 }
2659             }
2660             eof=0;
2661             continue;
2662         }
2663         ret = av_read_frame(ic, pkt);
2664         if (ret < 0) {
2665             if (ret == AVERROR_EOF || url_feof(ic->pb))
2666                 eof = 1;
2667             if (ic->pb && ic->pb->error)
2668                 break;
2669             SDL_Delay(100); /* wait for user event */
2670             continue;
2671         }
2672         /* check if packet is in play range specified by user, then queue, otherwise discard */
2673         pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2674                 (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
2675                 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2676                 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2677                 <= ((double)duration / 1000000);
2678         if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2679             packet_queue_put(&is->audioq, pkt);
2680         } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
2681             packet_queue_put(&is->videoq, pkt);
2682         } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2683             packet_queue_put(&is->subtitleq, pkt);
2684         } else {
2685             av_free_packet(pkt);
2686         }
2687     }
2688     /* wait until the end */
2689     while (!is->abort_request) {
2690         SDL_Delay(100);
2691     }
2692
2693     ret = 0;
2694  fail:
2695     /* close each stream */
2696     if (is->audio_stream >= 0)
2697         stream_component_close(is, is->audio_stream);
2698     if (is->video_stream >= 0)
2699         stream_component_close(is, is->video_stream);
2700     if (is->subtitle_stream >= 0)
2701         stream_component_close(is, is->subtitle_stream);
2702     if (is->ic) {
2703         avformat_close_input(&is->ic);
2704     }
2705
2706     if (ret != 0) {
2707         SDL_Event event;
2708
2709         event.type = FF_QUIT_EVENT;
2710         event.user.data1 = is;
2711         SDL_PushEvent(&event);
2712     }
2713     return 0;
2714 }
2715
2716 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2717 {
2718     VideoState *is;
2719
2720     is = av_mallocz(sizeof(VideoState));
2721     if (!is)
2722         return NULL;
2723     av_strlcpy(is->filename, filename, sizeof(is->filename));
2724     is->iformat = iformat;
2725     is->ytop    = 0;
2726     is->xleft   = 0;
2727
2728     /* start video display */
2729     is->pictq_mutex = SDL_CreateMutex();
2730     is->pictq_cond  = SDL_CreateCond();
2731
2732     is->subpq_mutex = SDL_CreateMutex();
2733     is->subpq_cond  = SDL_CreateCond();
2734
2735     is->av_sync_type = av_sync_type;
2736     is->read_tid     = SDL_CreateThread(read_thread, is);
2737     if (!is->read_tid) {
2738         av_free(is);
2739         return NULL;
2740     }
2741     return is;
2742 }
2743
2744 static void stream_cycle_channel(VideoState *is, int codec_type)
2745 {
2746     AVFormatContext *ic = is->ic;
2747     int start_index, stream_index;
2748     AVStream *st;
2749
2750     if (codec_type == AVMEDIA_TYPE_VIDEO)
2751         start_index = is->video_stream;
2752     else if (codec_type == AVMEDIA_TYPE_AUDIO)
2753         start_index = is->audio_stream;
2754     else
2755         start_index = is->subtitle_stream;
2756     if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
2757         return;
2758     stream_index = start_index;
2759     for (;;) {
2760         if (++stream_index >= is->ic->nb_streams)
2761         {
2762             if (codec_type == AVMEDIA_TYPE_SUBTITLE)
2763             {
2764                 stream_index = -1;
2765                 goto the_end;
2766             } else
2767                 stream_index = 0;
2768         }
2769         if (stream_index == start_index)
2770             return;
2771         st = ic->streams[stream_index];
2772         if (st->codec->codec_type == codec_type) {
2773             /* check that parameters are OK */
2774             switch (codec_type) {
2775             case AVMEDIA_TYPE_AUDIO:
2776                 if (st->codec->sample_rate != 0 &&
2777                     st->codec->channels != 0)
2778                     goto the_end;
2779                 break;
2780             case AVMEDIA_TYPE_VIDEO:
2781             case AVMEDIA_TYPE_SUBTITLE:
2782                 goto the_end;
2783             default:
2784                 break;
2785             }
2786         }
2787     }
2788  the_end:
2789     stream_component_close(is, start_index);
2790     stream_component_open(is, stream_index);
2791 }
2792
2793
2794 static void toggle_full_screen(VideoState *is)
2795 {
2796     av_unused int i;
2797     is_full_screen = !is_full_screen;
2798 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
2799     /* OS X needs to reallocate the SDL overlays */
2800     for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
2801         is->pictq[i].reallocate = 1;
2802     }
2803 #endif
2804     video_open(is, 1);
2805 }
2806
2807 static void toggle_pause(VideoState *is)
2808 {
2809     stream_toggle_pause(is);
2810     is->step = 0;
2811 }
2812
2813 static void step_to_next_frame(VideoState *is)
2814 {
2815     /* if the stream is paused unpause it, then step */
2816     if (is->paused)
2817         stream_toggle_pause(is);
2818     is->step = 1;
2819 }
2820
2821 static void toggle_audio_display(VideoState *is)
2822 {
2823     int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
2824     is->show_mode = (is->show_mode + 1) % SHOW_MODE_NB;
2825     fill_rectangle(screen,
2826                 is->xleft, is->ytop, is->width, is->height,
2827                 bgcolor);
2828     SDL_UpdateRect(screen, is->xleft, is->ytop, is->width, is->height);
2829 }
2830
2831 /* handle an event sent by the GUI */
2832 static void event_loop(VideoState *cur_stream)
2833 {
2834     SDL_Event event;
2835     double incr, pos, frac;
2836
2837     for (;;) {
2838         double x;
2839         SDL_WaitEvent(&event);
2840         switch (event.type) {
2841         case SDL_KEYDOWN:
2842             if (exit_on_keydown) {
2843                 do_exit(cur_stream);
2844                 break;
2845             }
2846             switch (event.key.keysym.sym) {
2847             case SDLK_ESCAPE:
2848             case SDLK_q:
2849                 do_exit(cur_stream);
2850                 break;
2851             case SDLK_f:
2852                 toggle_full_screen(cur_stream);
2853                 cur_stream->force_refresh = 1;
2854                 break;
2855             case SDLK_p:
2856             case SDLK_SPACE:
2857                 toggle_pause(cur_stream);
2858                 break;
2859             case SDLK_s: // S: Step to next frame
2860                 step_to_next_frame(cur_stream);
2861                 break;
2862             case SDLK_a:
2863                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
2864                 break;
2865             case SDLK_v:
2866                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
2867                 break;
2868             case SDLK_t:
2869                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
2870                 break;
2871             case SDLK_w:
2872                 toggle_audio_display(cur_stream);
2873                 cur_stream->force_refresh = 1;
2874                 break;
2875             case SDLK_PAGEUP:
2876                 incr = 600.0;
2877                 goto do_seek;
2878             case SDLK_PAGEDOWN:
2879                 incr = -600.0;
2880                 goto do_seek;
2881             case SDLK_LEFT:
2882                 incr = -10.0;
2883                 goto do_seek;
2884             case SDLK_RIGHT:
2885                 incr = 10.0;
2886                 goto do_seek;
2887             case SDLK_UP:
2888                 incr = 60.0;
2889                 goto do_seek;
2890             case SDLK_DOWN:
2891                 incr = -60.0;
2892             do_seek:
2893                     if (seek_by_bytes) {
2894                         if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
2895                             pos = cur_stream->video_current_pos;
2896                         } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
2897                             pos = cur_stream->audio_pkt.pos;
2898                         } else
2899                             pos = avio_tell(cur_stream->ic->pb);
2900                         if (cur_stream->ic->bit_rate)
2901                             incr *= cur_stream->ic->bit_rate / 8.0;
2902                         else
2903                             incr *= 180000.0;
2904                         pos += incr;
2905                         stream_seek(cur_stream, pos, incr, 1);
2906                     } else {
2907                         pos = get_master_clock(cur_stream);
2908                         pos += incr;
2909                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2910                     }
2911                 break;
2912             default:
2913                 break;
2914             }
2915             break;
2916         case SDL_VIDEOEXPOSE:
2917             cur_stream->force_refresh = 1;
2918             break;
2919         case SDL_MOUSEBUTTONDOWN:
2920             if (exit_on_mousedown) {
2921                 do_exit(cur_stream);
2922                 break;
2923             }
2924         case SDL_MOUSEMOTION:
2925             if (event.type == SDL_MOUSEBUTTONDOWN) {
2926                 x = event.button.x;
2927             } else {
2928                 if (event.motion.state != SDL_PRESSED)
2929                     break;
2930                 x = event.motion.x;
2931             }
2932                 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
2933                     uint64_t size =  avio_size(cur_stream->ic->pb);
2934                     stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
2935                 } else {
2936                     int64_t ts;
2937                     int ns, hh, mm, ss;
2938                     int tns, thh, tmm, tss;
2939                     tns  = cur_stream->ic->duration / 1000000LL;
2940                     thh  = tns / 3600;
2941                     tmm  = (tns % 3600) / 60;
2942                     tss  = (tns % 60);
2943                     frac = x / cur_stream->width;
2944                     ns   = frac * tns;
2945                     hh   = ns / 3600;
2946                     mm   = (ns % 3600) / 60;
2947                     ss   = (ns % 60);
2948                     fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2949                             hh, mm, ss, thh, tmm, tss);
2950                     ts = frac * cur_stream->ic->duration;
2951                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2952                         ts += cur_stream->ic->start_time;
2953                     stream_seek(cur_stream, ts, 0, 0);
2954                 }
2955             break;
2956         case SDL_VIDEORESIZE:
2957                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2958                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2959                 screen_width  = cur_stream->width  = event.resize.w;
2960                 screen_height = cur_stream->height = event.resize.h;
2961                 cur_stream->force_refresh = 1;
2962             break;
2963         case SDL_QUIT:
2964         case FF_QUIT_EVENT:
2965             do_exit(cur_stream);
2966             break;
2967         case FF_ALLOC_EVENT:
2968             alloc_picture(event.user.data1);
2969             break;
2970         case FF_REFRESH_EVENT:
2971             video_refresh(event.user.data1);
2972             cur_stream->refresh = 0;
2973             break;
2974         default:
2975             break;
2976         }
2977     }
2978 }
2979
2980 static int opt_frame_size(const char *opt, const char *arg)
2981 {
2982     av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
2983     return opt_default("video_size", arg);
2984 }
2985
2986 static int opt_width(const char *opt, const char *arg)
2987 {
2988     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2989     return 0;
2990 }
2991
2992 static int opt_height(const char *opt, const char *arg)
2993 {
2994     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2995     return 0;
2996 }
2997
2998 static int opt_format(const char *opt, const char *arg)
2999 {
3000     file_iformat = av_find_input_format(arg);
3001     if (!file_iformat) {
3002         fprintf(stderr, "Unknown input format: %s\n", arg);
3003         return AVERROR(EINVAL);
3004     }
3005     return 0;
3006 }
3007
3008 static int opt_frame_pix_fmt(const char *opt, const char *arg)
3009 {
3010     av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3011     return opt_default("pixel_format", arg);
3012 }
3013
3014 static int opt_sync(const char *opt, const char *arg)
3015 {
3016     if (!strcmp(arg, "audio"))
3017         av_sync_type = AV_SYNC_AUDIO_MASTER;
3018     else if (!strcmp(arg, "video"))
3019         av_sync_type = AV_SYNC_VIDEO_MASTER;
3020     else if (!strcmp(arg, "ext"))
3021         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3022     else {
3023         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
3024         exit(1);
3025     }
3026     return 0;
3027 }
3028
3029 static int opt_seek(const char *opt, const char *arg)
3030 {
3031     start_time = parse_time_or_die(opt, arg, 1);
3032     return 0;
3033 }
3034
3035 static int opt_duration(const char *opt, const char *arg)
3036 {
3037     duration = parse_time_or_die(opt, arg, 1);
3038     return 0;
3039 }
3040
3041 static int opt_show_mode(const char *opt, const char *arg)
3042 {
3043     show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3044                 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3045                 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT  :
3046                 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3047     return 0;
3048 }
3049
3050 static void opt_input_file(void *optctx, const char *filename)
3051 {
3052     if (input_filename) {
3053         fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3054                 filename, input_filename);
3055         exit_program(1);
3056     }
3057     if (!strcmp(filename, "-"))
3058         filename = "pipe:";
3059     input_filename = filename;
3060 }
3061
3062 static int opt_codec(void *o, const char *opt, const char *arg)
3063 {
3064     switch(opt[strlen(opt)-1]){
3065     case 'a' :    audio_codec_name = arg; break;
3066     case 's' : subtitle_codec_name = arg; break;
3067     case 'v' :    video_codec_name = arg; break;
3068     }
3069     return 0;
3070 }
3071
3072 static int dummy;
3073
3074 static const OptionDef options[] = {
3075 #include "cmdutils_common_opts.h"
3076     { "x", HAS_ARG, { (void*)opt_width }, "force displayed width", "width" },
3077     { "y", HAS_ARG, { (void*)opt_height }, "force displayed height", "height" },
3078     { "s", HAS_ARG | OPT_VIDEO, { (void*)opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3079     { "fs", OPT_BOOL, { (void*)&is_full_screen }, "force full screen" },
3080     { "an", OPT_BOOL, { (void*)&audio_disable }, "disable audio" },
3081     { "vn", OPT_BOOL, { (void*)&video_disable }, "disable video" },
3082     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3083     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3084     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3085     { "ss", HAS_ARG, { (void*)&opt_seek }, "seek to a given position in seconds", "pos" },
3086     { "t", HAS_ARG, { (void*)&opt_duration }, "play  \"duration\" seconds of audio/video", "duration" },
3087     { "bytes", OPT_INT | HAS_ARG, { (void*)&seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3088     { "nodisp", OPT_BOOL, { (void*)&display_disable }, "disable graphical display" },
3089     { "f", HAS_ARG, { (void*)opt_format }, "force format", "fmt" },
3090     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { (void*)opt_frame_pix_fmt }, "set pixel format", "format" },
3091     { "stats", OPT_BOOL | OPT_EXPERT, { (void*)&show_status }, "show status", "" },
3092     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&workaround_bugs }, "workaround bugs", "" },
3093     { "fast", OPT_BOOL | OPT_EXPERT, { (void*)&fast }, "non spec compliant optimizations", "" },
3094     { "genpts", OPT_BOOL | OPT_EXPERT, { (void*)&genpts }, "generate pts", "" },
3095     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3096     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&lowres }, "", "" },
3097     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_loop_filter }, "", "" },
3098     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_frame }, "", "" },
3099     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_idct }, "", "" },
3100     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&idct }, "set idct algo",  "algo" },
3101     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&error_concealment }, "set error concealment options",  "bit_mask" },
3102     { "sync", HAS_ARG | OPT_EXPERT, { (void*)opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3103     { "autoexit", OPT_BOOL | OPT_EXPERT, { (void*)&autoexit }, "exit at the end", "" },
3104     { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { (void*)&exit_on_keydown }, "exit on key down", "" },
3105     { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { (void*)&exit_on_mousedown }, "exit on mouse down", "" },
3106     { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&loop }, "set number of times the playback shall be looped", "loop count" },
3107     { "framedrop", OPT_BOOL | OPT_EXPERT, { (void*)&framedrop }, "drop frames when cpu is too slow", "" },
3108     { "window_title", OPT_STRING | HAS_ARG, { (void*)&window_title }, "set window title", "window title" },
3109 #if CONFIG_AVFILTER
3110     { "vf", OPT_STRING | HAS_ARG, { (void*)&vfilters }, "video filters", "filter list" },
3111 #endif
3112     { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { (void*)&rdftspeed }, "rdft speed", "msecs" },
3113     { "showmode", HAS_ARG, {(void*)opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3114     { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { (void*)opt_default }, "generic catch all option", "" },
3115     { "i", OPT_BOOL, {(void *)&dummy}, "read specified file", "input_file"},
3116     { "codec", HAS_ARG | OPT_FUNC2, {(void*)opt_codec}, "force decoder", "decoder" },
3117     { NULL, },
3118 };
3119
3120 static void show_usage(void)
3121 {
3122     av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3123     av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3124     av_log(NULL, AV_LOG_INFO, "\n");
3125 }
3126
3127 static int opt_help(const char *opt, const char *arg)
3128 {
3129     av_log_set_callback(log_callback_help);
3130     show_usage();
3131     show_help_options(options, "Main options:\n",
3132                       OPT_EXPERT, 0);
3133     show_help_options(options, "\nAdvanced options:\n",
3134                       OPT_EXPERT, OPT_EXPERT);
3135     printf("\n");
3136     show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3137     show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3138 #if !CONFIG_AVFILTER
3139     show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3140 #endif
3141     printf("\nWhile playing:\n"
3142            "q, ESC              quit\n"
3143            "f                   toggle full screen\n"
3144            "p, SPC              pause\n"
3145            "a                   cycle audio channel\n"
3146            "v                   cycle video channel\n"
3147            "t                   cycle subtitle channel\n"
3148            "w                   show audio waves\n"
3149            "s                   activate frame-step mode\n"
3150            "left/right          seek backward/forward 10 seconds\n"
3151            "down/up             seek backward/forward 1 minute\n"
3152            "page down/page up   seek backward/forward 10 minutes\n"
3153            "mouse click         seek to percentage in file corresponding to fraction of width\n"
3154            );
3155     return 0;
3156 }
3157
3158 static int lockmgr(void **mtx, enum AVLockOp op)
3159 {
3160    switch(op) {
3161       case AV_LOCK_CREATE:
3162           *mtx = SDL_CreateMutex();
3163           if(!*mtx)
3164               return 1;
3165           return 0;
3166       case AV_LOCK_OBTAIN:
3167           return !!SDL_LockMutex(*mtx);
3168       case AV_LOCK_RELEASE:
3169           return !!SDL_UnlockMutex(*mtx);
3170       case AV_LOCK_DESTROY:
3171           SDL_DestroyMutex(*mtx);
3172           return 0;
3173    }
3174    return 1;
3175 }
3176
3177 /* Called from the main */
3178 int main(int argc, char **argv)
3179 {
3180     int flags;
3181     VideoState *is;
3182
3183     av_log_set_flags(AV_LOG_SKIP_REPEATED);
3184     parse_loglevel(argc, argv, options);
3185
3186     /* register all codecs, demux and protocols */
3187     avcodec_register_all();
3188 #if CONFIG_AVDEVICE
3189     avdevice_register_all();
3190 #endif
3191 #if CONFIG_AVFILTER
3192     avfilter_register_all();
3193 #endif
3194     av_register_all();
3195     avformat_network_init();
3196
3197     init_opts();
3198
3199     signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
3200     signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
3201
3202     show_banner(argc, argv, options);
3203
3204     parse_options(NULL, argc, argv, options, opt_input_file);
3205
3206     if (!input_filename) {
3207         show_usage();
3208         fprintf(stderr, "An input file must be specified\n");
3209         fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3210         exit(1);
3211     }
3212
3213     if (display_disable) {
3214         video_disable = 1;
3215     }
3216     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3217     if (audio_disable)
3218         flags &= ~SDL_INIT_AUDIO;
3219 #if !defined(__MINGW32__) && !defined(__APPLE__)
3220     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3221 #endif
3222     if (SDL_Init (flags)) {
3223         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3224         fprintf(stderr, "(Did you set the DISPLAY variable?)\n");
3225         exit(1);
3226     }
3227
3228     if (!display_disable) {
3229 #if HAVE_SDL_VIDEO_SIZE
3230         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3231         fs_screen_width = vi->current_w;
3232         fs_screen_height = vi->current_h;
3233 #endif
3234     }
3235
3236     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3237     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3238     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3239
3240     if (av_lockmgr_register(lockmgr)) {
3241         fprintf(stderr, "Could not initialize lock manager!\n");
3242         do_exit(NULL);
3243     }
3244
3245     av_init_packet(&flush_pkt);
3246     flush_pkt.data = (char *)(intptr_t)"FLUSH";
3247
3248     is = stream_open(input_filename, file_iformat);
3249     if (!is) {
3250         fprintf(stderr, "Failed to initialize VideoState!\n");
3251         do_exit(NULL);
3252     }
3253
3254     event_loop(is);
3255
3256     /* never returns */
3257
3258     return 0;
3259 }