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