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