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