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