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