]> git.sesse.net Git - ffmpeg/blob - ffplay.c
122459abe639b23d8297e346e3b42e85484ed72e
[ffmpeg] / 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 <math.h>
24 #include <limits.h>
25 #include "libavutil/avstring.h"
26 #include "libavutil/pixdesc.h"
27 #include "libavformat/avformat.h"
28 #include "libavdevice/avdevice.h"
29 #include "libswscale/swscale.h"
30 #include "libavcodec/audioconvert.h"
31 #include "libavcodec/colorspace.h"
32 #include "libavcodec/opt.h"
33
34 #include "cmdutils.h"
35
36 #include <SDL.h>
37 #include <SDL_thread.h>
38
39 #ifdef __MINGW32__
40 #undef main /* We don't want SDL to override our main() */
41 #endif
42
43 #undef exit
44 #undef printf
45 #undef fprintf
46
47 const char program_name[] = "FFplay";
48 const int program_birth_year = 2003;
49
50 //#define DEBUG_SYNC
51
52 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
53 #define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
54 #define MIN_FRAMES 5
55
56 /* SDL audio buffer size, in samples. Should be small to have precise
57    A/V sync as SDL does not have hardware buffer fullness info. */
58 #define SDL_AUDIO_BUFFER_SIZE 1024
59
60 /* no AV sync correction is done if below the AV sync threshold */
61 #define AV_SYNC_THRESHOLD 0.01
62 /* no AV correction is done if too big error */
63 #define AV_NOSYNC_THRESHOLD 10.0
64
65 /* maximum audio speed change to get correct sync */
66 #define SAMPLE_CORRECTION_PERCENT_MAX 10
67
68 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
69 #define AUDIO_DIFF_AVG_NB   20
70
71 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
72 #define SAMPLE_ARRAY_SIZE (2*65536)
73
74 static int sws_flags = SWS_BICUBIC;
75
76 typedef struct PacketQueue {
77     AVPacketList *first_pkt, *last_pkt;
78     int nb_packets;
79     int size;
80     int abort_request;
81     SDL_mutex *mutex;
82     SDL_cond *cond;
83 } PacketQueue;
84
85 #define VIDEO_PICTURE_QUEUE_SIZE 1
86 #define SUBPICTURE_QUEUE_SIZE 4
87
88 typedef struct VideoPicture {
89     double pts;                                  ///<presentation time stamp for this picture
90     SDL_Overlay *bmp;
91     int width, height; /* source height & width */
92     int allocated;
93     SDL_TimerID timer_id;
94 } VideoPicture;
95
96 typedef struct SubPicture {
97     double pts; /* presentation time stamp for this picture */
98     AVSubtitle sub;
99 } SubPicture;
100
101 enum {
102     AV_SYNC_AUDIO_MASTER, /* default choice */
103     AV_SYNC_VIDEO_MASTER,
104     AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
105 };
106
107 typedef struct VideoState {
108     SDL_Thread *parse_tid;
109     SDL_Thread *video_tid;
110     AVInputFormat *iformat;
111     int no_background;
112     int abort_request;
113     int paused;
114     int last_paused;
115     int seek_req;
116     int seek_flags;
117     int64_t seek_pos;
118     int64_t seek_rel;
119     int read_pause_return;
120     AVFormatContext *ic;
121     int dtg_active_format;
122
123     int audio_stream;
124
125     int av_sync_type;
126     double external_clock; /* external clock base */
127     int64_t external_clock_time;
128
129     double audio_clock;
130     double audio_diff_cum; /* used for AV difference average computation */
131     double audio_diff_avg_coef;
132     double audio_diff_threshold;
133     int audio_diff_avg_count;
134     AVStream *audio_st;
135     PacketQueue audioq;
136     int audio_hw_buf_size;
137     /* samples output by the codec. we reserve more space for avsync
138        compensation */
139     DECLARE_ALIGNED(16,uint8_t,audio_buf1)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
140     DECLARE_ALIGNED(16,uint8_t,audio_buf2)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
141     uint8_t *audio_buf;
142     unsigned int audio_buf_size; /* in bytes */
143     int audio_buf_index; /* in bytes */
144     AVPacket audio_pkt_temp;
145     AVPacket audio_pkt;
146     enum SampleFormat audio_src_fmt;
147     AVAudioConvert *reformat_ctx;
148
149     int show_audio; /* if true, display audio samples */
150     int16_t sample_array[SAMPLE_ARRAY_SIZE];
151     int sample_array_index;
152     int last_i_start;
153
154     SDL_Thread *subtitle_tid;
155     int subtitle_stream;
156     int subtitle_stream_changed;
157     AVStream *subtitle_st;
158     PacketQueue subtitleq;
159     SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
160     int subpq_size, subpq_rindex, subpq_windex;
161     SDL_mutex *subpq_mutex;
162     SDL_cond *subpq_cond;
163
164     double frame_timer;
165     double frame_last_pts;
166     double frame_last_delay;
167     double video_clock;                          ///<pts of last decoded frame / predicted pts of next decoded frame
168     int video_stream;
169     AVStream *video_st;
170     PacketQueue videoq;
171     double video_current_pts;                    ///<current displayed pts (different from video_clock if frame fifos are used)
172     double video_current_pts_drift;              ///<video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
173     VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
174     int pictq_size, pictq_rindex, pictq_windex;
175     SDL_mutex *pictq_mutex;
176     SDL_cond *pictq_cond;
177     struct SwsContext *img_convert_ctx;
178
179     //    QETimer *video_timer;
180     char filename[1024];
181     int width, height, xleft, ytop;
182
183     int64_t faulty_pts;
184     int64_t faulty_dts;
185     int64_t last_dts_for_fault_detection;
186     int64_t last_pts_for_fault_detection;
187
188 } VideoState;
189
190 static void show_help(void);
191 static int audio_write_get_buf_size(VideoState *is);
192
193 /* options specified by the user */
194 static AVInputFormat *file_iformat;
195 static const char *input_filename;
196 static int fs_screen_width;
197 static int fs_screen_height;
198 static int screen_width = 0;
199 static int screen_height = 0;
200 static int frame_width = 0;
201 static int frame_height = 0;
202 static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
203 static int audio_disable;
204 static int video_disable;
205 static int wanted_audio_stream= 0;
206 static int wanted_video_stream= 0;
207 static int wanted_subtitle_stream= -1;
208 static int seek_by_bytes;
209 static int display_disable;
210 static int show_status = 1;
211 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
212 static int64_t start_time = AV_NOPTS_VALUE;
213 static int debug = 0;
214 static int debug_mv = 0;
215 static int step = 0;
216 static int thread_count = 1;
217 static int workaround_bugs = 1;
218 static int fast = 0;
219 static int genpts = 0;
220 static int lowres = 0;
221 static int idct = FF_IDCT_AUTO;
222 static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
223 static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
224 static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
225 static int error_recognition = FF_ER_CAREFUL;
226 static int error_concealment = 3;
227 static int decoder_reorder_pts= -1;
228
229 /* current context */
230 static int is_full_screen;
231 static VideoState *cur_stream;
232 static int64_t audio_callback_time;
233
234 static AVPacket flush_pkt;
235
236 #define FF_ALLOC_EVENT   (SDL_USEREVENT)
237 #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
238 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
239
240 static SDL_Surface *screen;
241
242 static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
243
244 /* packet queue handling */
245 static void packet_queue_init(PacketQueue *q)
246 {
247     memset(q, 0, sizeof(PacketQueue));
248     q->mutex = SDL_CreateMutex();
249     q->cond = SDL_CreateCond();
250     packet_queue_put(q, &flush_pkt);
251 }
252
253 static void packet_queue_flush(PacketQueue *q)
254 {
255     AVPacketList *pkt, *pkt1;
256
257     SDL_LockMutex(q->mutex);
258     for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
259         pkt1 = pkt->next;
260         av_free_packet(&pkt->pkt);
261         av_freep(&pkt);
262     }
263     q->last_pkt = NULL;
264     q->first_pkt = NULL;
265     q->nb_packets = 0;
266     q->size = 0;
267     SDL_UnlockMutex(q->mutex);
268 }
269
270 static void packet_queue_end(PacketQueue *q)
271 {
272     packet_queue_flush(q);
273     SDL_DestroyMutex(q->mutex);
274     SDL_DestroyCond(q->cond);
275 }
276
277 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
278 {
279     AVPacketList *pkt1;
280
281     /* duplicate the packet */
282     if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
283         return -1;
284
285     pkt1 = av_malloc(sizeof(AVPacketList));
286     if (!pkt1)
287         return -1;
288     pkt1->pkt = *pkt;
289     pkt1->next = NULL;
290
291
292     SDL_LockMutex(q->mutex);
293
294     if (!q->last_pkt)
295
296         q->first_pkt = pkt1;
297     else
298         q->last_pkt->next = pkt1;
299     q->last_pkt = pkt1;
300     q->nb_packets++;
301     q->size += pkt1->pkt.size + sizeof(*pkt1);
302     /* XXX: should duplicate packet data in DV case */
303     SDL_CondSignal(q->cond);
304
305     SDL_UnlockMutex(q->mutex);
306     return 0;
307 }
308
309 static void packet_queue_abort(PacketQueue *q)
310 {
311     SDL_LockMutex(q->mutex);
312
313     q->abort_request = 1;
314
315     SDL_CondSignal(q->cond);
316
317     SDL_UnlockMutex(q->mutex);
318 }
319
320 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
321 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
322 {
323     AVPacketList *pkt1;
324     int ret;
325
326     SDL_LockMutex(q->mutex);
327
328     for(;;) {
329         if (q->abort_request) {
330             ret = -1;
331             break;
332         }
333
334         pkt1 = q->first_pkt;
335         if (pkt1) {
336             q->first_pkt = pkt1->next;
337             if (!q->first_pkt)
338                 q->last_pkt = NULL;
339             q->nb_packets--;
340             q->size -= pkt1->pkt.size + sizeof(*pkt1);
341             *pkt = pkt1->pkt;
342             av_free(pkt1);
343             ret = 1;
344             break;
345         } else if (!block) {
346             ret = 0;
347             break;
348         } else {
349             SDL_CondWait(q->cond, q->mutex);
350         }
351     }
352     SDL_UnlockMutex(q->mutex);
353     return ret;
354 }
355
356 static inline void fill_rectangle(SDL_Surface *screen,
357                                   int x, int y, int w, int h, int color)
358 {
359     SDL_Rect rect;
360     rect.x = x;
361     rect.y = y;
362     rect.w = w;
363     rect.h = h;
364     SDL_FillRect(screen, &rect, color);
365 }
366
367 #if 0
368 /* draw only the border of a rectangle */
369 void fill_border(VideoState *s, int x, int y, int w, int h, int color)
370 {
371     int w1, w2, h1, h2;
372
373     /* fill the background */
374     w1 = x;
375     if (w1 < 0)
376         w1 = 0;
377     w2 = s->width - (x + w);
378     if (w2 < 0)
379         w2 = 0;
380     h1 = y;
381     if (h1 < 0)
382         h1 = 0;
383     h2 = s->height - (y + h);
384     if (h2 < 0)
385         h2 = 0;
386     fill_rectangle(screen,
387                    s->xleft, s->ytop,
388                    w1, s->height,
389                    color);
390     fill_rectangle(screen,
391                    s->xleft + s->width - w2, s->ytop,
392                    w2, s->height,
393                    color);
394     fill_rectangle(screen,
395                    s->xleft + w1, s->ytop,
396                    s->width - w1 - w2, h1,
397                    color);
398     fill_rectangle(screen,
399                    s->xleft + w1, s->ytop + s->height - h2,
400                    s->width - w1 - w2, h2,
401                    color);
402 }
403 #endif
404
405 #define ALPHA_BLEND(a, oldp, newp, s)\
406 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
407
408 #define RGBA_IN(r, g, b, a, s)\
409 {\
410     unsigned int v = ((const uint32_t *)(s))[0];\
411     a = (v >> 24) & 0xff;\
412     r = (v >> 16) & 0xff;\
413     g = (v >> 8) & 0xff;\
414     b = v & 0xff;\
415 }
416
417 #define YUVA_IN(y, u, v, a, s, pal)\
418 {\
419     unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
420     a = (val >> 24) & 0xff;\
421     y = (val >> 16) & 0xff;\
422     u = (val >> 8) & 0xff;\
423     v = val & 0xff;\
424 }
425
426 #define YUVA_OUT(d, y, u, v, a)\
427 {\
428     ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
429 }
430
431
432 #define BPP 1
433
434 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
435 {
436     int wrap, wrap3, width2, skip2;
437     int y, u, v, a, u1, v1, a1, w, h;
438     uint8_t *lum, *cb, *cr;
439     const uint8_t *p;
440     const uint32_t *pal;
441     int dstx, dsty, dstw, dsth;
442
443     dstw = av_clip(rect->w, 0, imgw);
444     dsth = av_clip(rect->h, 0, imgh);
445     dstx = av_clip(rect->x, 0, imgw - dstw);
446     dsty = av_clip(rect->y, 0, imgh - dsth);
447     lum = dst->data[0] + dsty * dst->linesize[0];
448     cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
449     cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
450
451     width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
452     skip2 = dstx >> 1;
453     wrap = dst->linesize[0];
454     wrap3 = rect->pict.linesize[0];
455     p = rect->pict.data[0];
456     pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
457
458     if (dsty & 1) {
459         lum += dstx;
460         cb += skip2;
461         cr += skip2;
462
463         if (dstx & 1) {
464             YUVA_IN(y, u, v, a, p, pal);
465             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
466             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
467             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
468             cb++;
469             cr++;
470             lum++;
471             p += BPP;
472         }
473         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
474             YUVA_IN(y, u, v, a, p, pal);
475             u1 = u;
476             v1 = v;
477             a1 = a;
478             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
479
480             YUVA_IN(y, u, v, a, p + BPP, pal);
481             u1 += u;
482             v1 += v;
483             a1 += a;
484             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
485             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
486             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
487             cb++;
488             cr++;
489             p += 2 * BPP;
490             lum += 2;
491         }
492         if (w) {
493             YUVA_IN(y, u, v, a, p, pal);
494             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
495             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
496             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
497             p++;
498             lum++;
499         }
500         p += wrap3 - dstw * BPP;
501         lum += wrap - dstw - dstx;
502         cb += dst->linesize[1] - width2 - skip2;
503         cr += dst->linesize[2] - width2 - skip2;
504     }
505     for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
506         lum += dstx;
507         cb += skip2;
508         cr += skip2;
509
510         if (dstx & 1) {
511             YUVA_IN(y, u, v, a, p, pal);
512             u1 = u;
513             v1 = v;
514             a1 = a;
515             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
516             p += wrap3;
517             lum += wrap;
518             YUVA_IN(y, u, v, a, p, pal);
519             u1 += u;
520             v1 += v;
521             a1 += a;
522             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
523             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
524             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
525             cb++;
526             cr++;
527             p += -wrap3 + BPP;
528             lum += -wrap + 1;
529         }
530         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
531             YUVA_IN(y, u, v, a, p, pal);
532             u1 = u;
533             v1 = v;
534             a1 = a;
535             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
536
537             YUVA_IN(y, u, v, a, p + BPP, pal);
538             u1 += u;
539             v1 += v;
540             a1 += a;
541             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
542             p += wrap3;
543             lum += wrap;
544
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
557             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
558             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
559
560             cb++;
561             cr++;
562             p += -wrap3 + 2 * BPP;
563             lum += -wrap + 2;
564         }
565         if (w) {
566             YUVA_IN(y, u, v, a, p, pal);
567             u1 = u;
568             v1 = v;
569             a1 = a;
570             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
571             p += wrap3;
572             lum += wrap;
573             YUVA_IN(y, u, v, a, p, pal);
574             u1 += u;
575             v1 += v;
576             a1 += a;
577             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
578             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
579             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
580             cb++;
581             cr++;
582             p += -wrap3 + BPP;
583             lum += -wrap + 1;
584         }
585         p += wrap3 + (wrap3 - dstw * BPP);
586         lum += wrap + (wrap - dstw - dstx);
587         cb += dst->linesize[1] - width2 - skip2;
588         cr += dst->linesize[2] - width2 - skip2;
589     }
590     /* handle odd height */
591     if (h) {
592         lum += dstx;
593         cb += skip2;
594         cr += skip2;
595
596         if (dstx & 1) {
597             YUVA_IN(y, u, v, a, p, pal);
598             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
599             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
600             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
601             cb++;
602             cr++;
603             lum++;
604             p += BPP;
605         }
606         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
607             YUVA_IN(y, u, v, a, p, pal);
608             u1 = u;
609             v1 = v;
610             a1 = a;
611             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
612
613             YUVA_IN(y, u, v, a, p + BPP, pal);
614             u1 += u;
615             v1 += v;
616             a1 += a;
617             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
618             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
619             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
620             cb++;
621             cr++;
622             p += 2 * BPP;
623             lum += 2;
624         }
625         if (w) {
626             YUVA_IN(y, u, v, a, p, pal);
627             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
628             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
629             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
630         }
631     }
632 }
633
634 static void free_subpicture(SubPicture *sp)
635 {
636     int i;
637
638     for (i = 0; i < sp->sub.num_rects; i++)
639     {
640         av_freep(&sp->sub.rects[i]->pict.data[0]);
641         av_freep(&sp->sub.rects[i]->pict.data[1]);
642         av_freep(&sp->sub.rects[i]);
643     }
644
645     av_free(sp->sub.rects);
646
647     memset(&sp->sub, 0, sizeof(AVSubtitle));
648 }
649
650 static void video_image_display(VideoState *is)
651 {
652     VideoPicture *vp;
653     SubPicture *sp;
654     AVPicture pict;
655     float aspect_ratio;
656     int width, height, x, y;
657     SDL_Rect rect;
658     int i;
659
660     vp = &is->pictq[is->pictq_rindex];
661     if (vp->bmp) {
662         /* XXX: use variable in the frame */
663         if (is->video_st->sample_aspect_ratio.num)
664             aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
665         else if (is->video_st->codec->sample_aspect_ratio.num)
666             aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
667         else
668             aspect_ratio = 0;
669         if (aspect_ratio <= 0.0)
670             aspect_ratio = 1.0;
671         aspect_ratio *= (float)is->video_st->codec->width / is->video_st->codec->height;
672         /* if an active format is indicated, then it overrides the
673            mpeg format */
674 #if 0
675         if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
676             is->dtg_active_format = is->video_st->codec->dtg_active_format;
677             printf("dtg_active_format=%d\n", is->dtg_active_format);
678         }
679 #endif
680 #if 0
681         switch(is->video_st->codec->dtg_active_format) {
682         case FF_DTG_AFD_SAME:
683         default:
684             /* nothing to do */
685             break;
686         case FF_DTG_AFD_4_3:
687             aspect_ratio = 4.0 / 3.0;
688             break;
689         case FF_DTG_AFD_16_9:
690             aspect_ratio = 16.0 / 9.0;
691             break;
692         case FF_DTG_AFD_14_9:
693             aspect_ratio = 14.0 / 9.0;
694             break;
695         case FF_DTG_AFD_4_3_SP_14_9:
696             aspect_ratio = 14.0 / 9.0;
697             break;
698         case FF_DTG_AFD_16_9_SP_14_9:
699             aspect_ratio = 14.0 / 9.0;
700             break;
701         case FF_DTG_AFD_SP_4_3:
702             aspect_ratio = 4.0 / 3.0;
703             break;
704         }
705 #endif
706
707         if (is->subtitle_st)
708         {
709             if (is->subpq_size > 0)
710             {
711                 sp = &is->subpq[is->subpq_rindex];
712
713                 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
714                 {
715                     SDL_LockYUVOverlay (vp->bmp);
716
717                     pict.data[0] = vp->bmp->pixels[0];
718                     pict.data[1] = vp->bmp->pixels[2];
719                     pict.data[2] = vp->bmp->pixels[1];
720
721                     pict.linesize[0] = vp->bmp->pitches[0];
722                     pict.linesize[1] = vp->bmp->pitches[2];
723                     pict.linesize[2] = vp->bmp->pitches[1];
724
725                     for (i = 0; i < sp->sub.num_rects; i++)
726                         blend_subrect(&pict, sp->sub.rects[i],
727                                       vp->bmp->w, vp->bmp->h);
728
729                     SDL_UnlockYUVOverlay (vp->bmp);
730                 }
731             }
732         }
733
734
735         /* XXX: we suppose the screen has a 1.0 pixel ratio */
736         height = is->height;
737         width = ((int)rint(height * aspect_ratio)) & ~1;
738         if (width > is->width) {
739             width = is->width;
740             height = ((int)rint(width / aspect_ratio)) & ~1;
741         }
742         x = (is->width - width) / 2;
743         y = (is->height - height) / 2;
744         if (!is->no_background) {
745             /* fill the background */
746             //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
747         } else {
748             is->no_background = 0;
749         }
750         rect.x = is->xleft + x;
751         rect.y = is->ytop  + y;
752         rect.w = width;
753         rect.h = height;
754         SDL_DisplayYUVOverlay(vp->bmp, &rect);
755     } else {
756 #if 0
757         fill_rectangle(screen,
758                        is->xleft, is->ytop, is->width, is->height,
759                        QERGB(0x00, 0x00, 0x00));
760 #endif
761     }
762 }
763
764 static inline int compute_mod(int a, int b)
765 {
766     a = a % b;
767     if (a >= 0)
768         return a;
769     else
770         return a + b;
771 }
772
773 static void video_audio_display(VideoState *s)
774 {
775     int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
776     int ch, channels, h, h2, bgcolor, fgcolor;
777     int16_t time_diff;
778
779     /* compute display index : center on currently output samples */
780     channels = s->audio_st->codec->channels;
781     nb_display_channels = channels;
782     if (!s->paused) {
783         n = 2 * channels;
784         delay = audio_write_get_buf_size(s);
785         delay /= n;
786
787         /* to be more precise, we take into account the time spent since
788            the last buffer computation */
789         if (audio_callback_time) {
790             time_diff = av_gettime() - audio_callback_time;
791             delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
792         }
793
794         delay -= s->width / 2;
795         if (delay < s->width)
796             delay = s->width;
797
798         i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
799
800         h= INT_MIN;
801         for(i=0; i<1000; i+=channels){
802             int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
803             int a= s->sample_array[idx];
804             int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
805             int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
806             int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
807             int score= a-d;
808             if(h<score && (b^c)<0){
809                 h= score;
810                 i_start= idx;
811             }
812         }
813
814         s->last_i_start = i_start;
815     } else {
816         i_start = s->last_i_start;
817     }
818
819     bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
820     fill_rectangle(screen,
821                    s->xleft, s->ytop, s->width, s->height,
822                    bgcolor);
823
824     fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
825
826     /* total height for one channel */
827     h = s->height / nb_display_channels;
828     /* graph height / 2 */
829     h2 = (h * 9) / 20;
830     for(ch = 0;ch < nb_display_channels; ch++) {
831         i = i_start + ch;
832         y1 = s->ytop + ch * h + (h / 2); /* position of center line */
833         for(x = 0; x < s->width; x++) {
834             y = (s->sample_array[i] * h2) >> 15;
835             if (y < 0) {
836                 y = -y;
837                 ys = y1 - y;
838             } else {
839                 ys = y1;
840             }
841             fill_rectangle(screen,
842                            s->xleft + x, ys, 1, y,
843                            fgcolor);
844             i += channels;
845             if (i >= SAMPLE_ARRAY_SIZE)
846                 i -= SAMPLE_ARRAY_SIZE;
847         }
848     }
849
850     fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
851
852     for(ch = 1;ch < nb_display_channels; ch++) {
853         y = s->ytop + ch * h;
854         fill_rectangle(screen,
855                        s->xleft, y, s->width, 1,
856                        fgcolor);
857     }
858     SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
859 }
860
861 static int video_open(VideoState *is){
862     int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
863     int w,h;
864
865     if(is_full_screen) flags |= SDL_FULLSCREEN;
866     else               flags |= SDL_RESIZABLE;
867
868     if (is_full_screen && fs_screen_width) {
869         w = fs_screen_width;
870         h = fs_screen_height;
871     } else if(!is_full_screen && screen_width){
872         w = screen_width;
873         h = screen_height;
874     }else if (is->video_st && is->video_st->codec->width){
875         w = is->video_st->codec->width;
876         h = is->video_st->codec->height;
877     } else {
878         w = 640;
879         h = 480;
880     }
881 #ifndef __APPLE__
882     screen = SDL_SetVideoMode(w, h, 0, flags);
883 #else
884     /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
885     screen = SDL_SetVideoMode(w, h, 24, flags);
886 #endif
887     if (!screen) {
888         fprintf(stderr, "SDL: could not set video mode - exiting\n");
889         return -1;
890     }
891     SDL_WM_SetCaption("FFplay", "FFplay");
892
893     is->width = screen->w;
894     is->height = screen->h;
895
896     return 0;
897 }
898
899 /* display the current picture, if any */
900 static void video_display(VideoState *is)
901 {
902     if(!screen)
903         video_open(cur_stream);
904     if (is->audio_st && is->show_audio)
905         video_audio_display(is);
906     else if (is->video_st)
907         video_image_display(is);
908 }
909
910 static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
911 {
912     SDL_Event event;
913     event.type = FF_REFRESH_EVENT;
914     event.user.data1 = opaque;
915     SDL_PushEvent(&event);
916     return 0; /* 0 means stop timer */
917 }
918
919 /* schedule a video refresh in 'delay' ms */
920 static SDL_TimerID schedule_refresh(VideoState *is, int delay)
921 {
922     if(!delay) delay=1; //SDL seems to be buggy when the delay is 0
923     return SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
924 }
925
926 /* get the current audio clock value */
927 static double get_audio_clock(VideoState *is)
928 {
929     double pts;
930     int hw_buf_size, bytes_per_sec;
931     pts = is->audio_clock;
932     hw_buf_size = audio_write_get_buf_size(is);
933     bytes_per_sec = 0;
934     if (is->audio_st) {
935         bytes_per_sec = is->audio_st->codec->sample_rate *
936             2 * is->audio_st->codec->channels;
937     }
938     if (bytes_per_sec)
939         pts -= (double)hw_buf_size / bytes_per_sec;
940     return pts;
941 }
942
943 /* get the current video clock value */
944 static double get_video_clock(VideoState *is)
945 {
946     if (is->paused) {
947         return is->video_current_pts;
948     } else {
949         return is->video_current_pts_drift + av_gettime() / 1000000.0;
950     }
951 }
952
953 /* get the current external clock value */
954 static double get_external_clock(VideoState *is)
955 {
956     int64_t ti;
957     ti = av_gettime();
958     return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
959 }
960
961 /* get the current master clock value */
962 static double get_master_clock(VideoState *is)
963 {
964     double val;
965
966     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
967         if (is->video_st)
968             val = get_video_clock(is);
969         else
970             val = get_audio_clock(is);
971     } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
972         if (is->audio_st)
973             val = get_audio_clock(is);
974         else
975             val = get_video_clock(is);
976     } else {
977         val = get_external_clock(is);
978     }
979     return val;
980 }
981
982 /* seek in the stream */
983 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
984 {
985     if (!is->seek_req) {
986         is->seek_pos = pos;
987         is->seek_rel = rel;
988         if (seek_by_bytes)
989             is->seek_flags |= AVSEEK_FLAG_BYTE;
990         is->seek_req = 1;
991     }
992 }
993
994 /* pause or resume the video */
995 static void stream_pause(VideoState *is)
996 {
997     if (is->paused) {
998         is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
999         if(is->read_pause_return != AVERROR(ENOSYS)){
1000             is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1001         }
1002         is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1003     }
1004     is->paused = !is->paused;
1005 }
1006
1007 static double compute_frame_delay(double frame_current_pts, VideoState *is)
1008 {
1009     double actual_delay, delay, sync_threshold, ref_clock, diff;
1010
1011     /* compute nominal delay */
1012     delay = frame_current_pts - is->frame_last_pts;
1013     if (delay <= 0 || delay >= 10.0) {
1014         /* if incorrect delay, use previous one */
1015         delay = is->frame_last_delay;
1016     } else {
1017         is->frame_last_delay = delay;
1018     }
1019     is->frame_last_pts = frame_current_pts;
1020
1021     /* update delay to follow master synchronisation source */
1022     if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1023          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1024         /* if video is slave, we try to correct big delays by
1025            duplicating or deleting a frame */
1026         ref_clock = get_master_clock(is);
1027         diff = frame_current_pts - ref_clock;
1028
1029         /* skip or repeat frame. We take into account the
1030            delay to compute the threshold. I still don't know
1031            if it is the best guess */
1032         sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1033         if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1034             if (diff <= -sync_threshold)
1035                 delay = 0;
1036             else if (diff >= sync_threshold)
1037                 delay = 2 * delay;
1038         }
1039     }
1040
1041     is->frame_timer += delay;
1042     /* compute the REAL delay (we need to do that to avoid
1043        long term errors */
1044     actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1045     if (actual_delay < 0.010) {
1046         /* XXX: should skip picture */
1047         actual_delay = 0.010;
1048     }
1049
1050 #if defined(DEBUG_SYNC)
1051     printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1052             delay, actual_delay, frame_current_pts, -diff);
1053 #endif
1054
1055     return actual_delay;
1056 }
1057
1058 /* called to display each frame */
1059 static void video_refresh_timer(void *opaque)
1060 {
1061     VideoState *is = opaque;
1062     VideoPicture *vp;
1063
1064     SubPicture *sp, *sp2;
1065
1066     if (is->video_st) {
1067         if (is->pictq_size == 0) {
1068 //            fprintf(stderr, "Internal error detected in the SDL timer\n");
1069         } else {
1070             /* dequeue the picture */
1071             vp = &is->pictq[is->pictq_rindex];
1072
1073             /* update current video pts */
1074             is->video_current_pts = vp->pts;
1075             is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1076
1077             if(is->subtitle_st) {
1078                 if (is->subtitle_stream_changed) {
1079                     SDL_LockMutex(is->subpq_mutex);
1080
1081                     while (is->subpq_size) {
1082                         free_subpicture(&is->subpq[is->subpq_rindex]);
1083
1084                         /* update queue size and signal for next picture */
1085                         if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1086                             is->subpq_rindex = 0;
1087
1088                         is->subpq_size--;
1089                     }
1090                     is->subtitle_stream_changed = 0;
1091
1092                     SDL_CondSignal(is->subpq_cond);
1093                     SDL_UnlockMutex(is->subpq_mutex);
1094                 } else {
1095                     if (is->subpq_size > 0) {
1096                         sp = &is->subpq[is->subpq_rindex];
1097
1098                         if (is->subpq_size > 1)
1099                             sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1100                         else
1101                             sp2 = NULL;
1102
1103                         if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1104                                 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1105                         {
1106                             free_subpicture(sp);
1107
1108                             /* update queue size and signal for next picture */
1109                             if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1110                                 is->subpq_rindex = 0;
1111
1112                             SDL_LockMutex(is->subpq_mutex);
1113                             is->subpq_size--;
1114                             SDL_CondSignal(is->subpq_cond);
1115                             SDL_UnlockMutex(is->subpq_mutex);
1116                         }
1117                     }
1118                 }
1119             }
1120
1121             /* display picture */
1122             video_display(is);
1123
1124             /* update queue size and signal for next picture */
1125             if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1126                 is->pictq_rindex = 0;
1127
1128             SDL_LockMutex(is->pictq_mutex);
1129             vp->timer_id= 0;
1130             is->pictq_size--;
1131             SDL_CondSignal(is->pictq_cond);
1132             SDL_UnlockMutex(is->pictq_mutex);
1133         }
1134     } else if (is->audio_st) {
1135         /* draw the next audio frame */
1136
1137         schedule_refresh(is, 40);
1138
1139         /* if only audio stream, then display the audio bars (better
1140            than nothing, just to test the implementation */
1141
1142         /* display picture */
1143         video_display(is);
1144     } else {
1145         schedule_refresh(is, 100);
1146     }
1147     if (show_status) {
1148         static int64_t last_time;
1149         int64_t cur_time;
1150         int aqsize, vqsize, sqsize;
1151         double av_diff;
1152
1153         cur_time = av_gettime();
1154         if (!last_time || (cur_time - last_time) >= 30000) {
1155             aqsize = 0;
1156             vqsize = 0;
1157             sqsize = 0;
1158             if (is->audio_st)
1159                 aqsize = is->audioq.size;
1160             if (is->video_st)
1161                 vqsize = is->videoq.size;
1162             if (is->subtitle_st)
1163                 sqsize = is->subtitleq.size;
1164             av_diff = 0;
1165             if (is->audio_st && is->video_st)
1166                 av_diff = get_audio_clock(is) - get_video_clock(is);
1167             printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB f=%Ld/%Ld   \r",
1168                    get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts);
1169             fflush(stdout);
1170             last_time = cur_time;
1171         }
1172     }
1173 }
1174
1175 /* allocate a picture (needs to do that in main thread to avoid
1176    potential locking problems */
1177 static void alloc_picture(void *opaque)
1178 {
1179     VideoState *is = opaque;
1180     VideoPicture *vp;
1181
1182     vp = &is->pictq[is->pictq_windex];
1183
1184     if (vp->bmp)
1185         SDL_FreeYUVOverlay(vp->bmp);
1186
1187     vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1188                                    is->video_st->codec->height,
1189                                    SDL_YV12_OVERLAY,
1190                                    screen);
1191     vp->width = is->video_st->codec->width;
1192     vp->height = is->video_st->codec->height;
1193
1194     SDL_LockMutex(is->pictq_mutex);
1195     vp->allocated = 1;
1196     SDL_CondSignal(is->pictq_cond);
1197     SDL_UnlockMutex(is->pictq_mutex);
1198 }
1199
1200 /**
1201  *
1202  * @param pts the dts of the pkt / pts of the frame and guessed if not known
1203  */
1204 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1205 {
1206     VideoPicture *vp;
1207     int dst_pix_fmt;
1208
1209     /* wait until we have space to put a new picture */
1210     SDL_LockMutex(is->pictq_mutex);
1211     while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1212            !is->videoq.abort_request) {
1213         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1214     }
1215     SDL_UnlockMutex(is->pictq_mutex);
1216
1217     if (is->videoq.abort_request)
1218         return -1;
1219
1220     vp = &is->pictq[is->pictq_windex];
1221
1222     /* alloc or resize hardware picture buffer */
1223     if (!vp->bmp ||
1224         vp->width != is->video_st->codec->width ||
1225         vp->height != is->video_st->codec->height) {
1226         SDL_Event event;
1227
1228         vp->allocated = 0;
1229
1230         /* the allocation must be done in the main thread to avoid
1231            locking problems */
1232         event.type = FF_ALLOC_EVENT;
1233         event.user.data1 = is;
1234         SDL_PushEvent(&event);
1235
1236         /* wait until the picture is allocated */
1237         SDL_LockMutex(is->pictq_mutex);
1238         while (!vp->allocated && !is->videoq.abort_request) {
1239             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1240         }
1241         SDL_UnlockMutex(is->pictq_mutex);
1242
1243         if (is->videoq.abort_request)
1244             return -1;
1245     }
1246
1247     /* if the frame is not skipped, then display it */
1248     if (vp->bmp) {
1249         AVPicture pict;
1250
1251         /* get a pointer on the bitmap */
1252         SDL_LockYUVOverlay (vp->bmp);
1253
1254         dst_pix_fmt = PIX_FMT_YUV420P;
1255         memset(&pict,0,sizeof(AVPicture));
1256         pict.data[0] = vp->bmp->pixels[0];
1257         pict.data[1] = vp->bmp->pixels[2];
1258         pict.data[2] = vp->bmp->pixels[1];
1259
1260         pict.linesize[0] = vp->bmp->pitches[0];
1261         pict.linesize[1] = vp->bmp->pitches[2];
1262         pict.linesize[2] = vp->bmp->pitches[1];
1263         sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1264         is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1265             is->video_st->codec->width, is->video_st->codec->height,
1266             is->video_st->codec->pix_fmt,
1267             is->video_st->codec->width, is->video_st->codec->height,
1268             dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1269         if (is->img_convert_ctx == NULL) {
1270             fprintf(stderr, "Cannot initialize the conversion context\n");
1271             exit(1);
1272         }
1273         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1274                   0, is->video_st->codec->height, pict.data, pict.linesize);
1275         /* update the bitmap content */
1276         SDL_UnlockYUVOverlay(vp->bmp);
1277
1278         vp->pts = pts;
1279
1280         /* now we can update the picture count */
1281         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1282             is->pictq_windex = 0;
1283         SDL_LockMutex(is->pictq_mutex);
1284         is->pictq_size++;
1285         //We must schedule in a mutex as we must store the timer id before the timer dies or might end up freeing a alraedy freed id
1286         vp->timer_id= schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1287         SDL_UnlockMutex(is->pictq_mutex);
1288     }
1289     return 0;
1290 }
1291
1292 /**
1293  * compute the exact PTS for the picture if it is omitted in the stream
1294  * @param pts1 the dts of the pkt / pts of the frame
1295  */
1296 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1297 {
1298     double frame_delay, pts;
1299
1300     pts = pts1;
1301
1302     if (pts != 0) {
1303         /* update video clock with pts, if present */
1304         is->video_clock = pts;
1305     } else {
1306         pts = is->video_clock;
1307     }
1308     /* update video clock for next frame */
1309     frame_delay = av_q2d(is->video_st->codec->time_base);
1310     /* for MPEG2, the frame can be repeated, so we update the
1311        clock accordingly */
1312     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1313     is->video_clock += frame_delay;
1314
1315 #if defined(DEBUG_SYNC) && 0
1316     {
1317         int ftype;
1318         if (src_frame->pict_type == FF_B_TYPE)
1319             ftype = 'B';
1320         else if (src_frame->pict_type == FF_I_TYPE)
1321             ftype = 'I';
1322         else
1323             ftype = 'P';
1324         printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1325                ftype, pts, pts1);
1326     }
1327 #endif
1328     return queue_picture(is, src_frame, pts);
1329 }
1330
1331 static int video_thread(void *arg)
1332 {
1333     VideoState *is = arg;
1334     AVPacket pkt1, *pkt = &pkt1;
1335     int len1, got_picture, i;
1336     AVFrame *frame= avcodec_alloc_frame();
1337     double pts;
1338
1339     for(;;) {
1340         while (is->paused && !is->videoq.abort_request) {
1341             SDL_Delay(10);
1342         }
1343         if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1344             break;
1345
1346         if(pkt->data == flush_pkt.data){
1347             avcodec_flush_buffers(is->video_st->codec);
1348
1349             SDL_LockMutex(is->pictq_mutex);
1350             //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1351             for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){
1352                 if(is->pictq[i].timer_id){
1353                     SDL_RemoveTimer(is->pictq[i].timer_id);
1354                     is->pictq[i].timer_id=0;
1355                     schedule_refresh(is, 1);
1356                 }
1357             }
1358             while (is->pictq_size && !is->videoq.abort_request) {
1359                 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1360             }
1361             SDL_UnlockMutex(is->pictq_mutex);
1362
1363             is->last_dts_for_fault_detection=
1364             is->last_pts_for_fault_detection= INT64_MIN;
1365             is->frame_last_pts= AV_NOPTS_VALUE;
1366
1367             continue;
1368         }
1369
1370         /* NOTE: ipts is the PTS of the _first_ picture beginning in
1371            this packet, if any */
1372         is->video_st->codec->reordered_opaque= pkt->pts;
1373         len1 = avcodec_decode_video2(is->video_st->codec,
1374                                     frame, &got_picture,
1375                                     pkt);
1376
1377         if(pkt->dts != AV_NOPTS_VALUE){
1378             is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1379             is->last_dts_for_fault_detection= pkt->dts;
1380         }
1381         if(frame->reordered_opaque != AV_NOPTS_VALUE){
1382             is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1383             is->last_pts_for_fault_detection= frame->reordered_opaque;
1384         }
1385
1386         if(   (   decoder_reorder_pts==1
1387                || decoder_reorder_pts && is->faulty_pts<is->faulty_dts
1388                || pkt->dts == AV_NOPTS_VALUE)
1389            && frame->reordered_opaque != AV_NOPTS_VALUE)
1390             pts= frame->reordered_opaque;
1391         else if(pkt->dts != AV_NOPTS_VALUE)
1392             pts= pkt->dts;
1393         else
1394             pts= 0;
1395         pts *= av_q2d(is->video_st->time_base);
1396
1397 //            if (len1 < 0)
1398 //                break;
1399         if (got_picture) {
1400             if (output_picture2(is, frame, pts) < 0)
1401                 goto the_end;
1402         }
1403         av_free_packet(pkt);
1404         if (step)
1405             if (cur_stream)
1406                 stream_pause(cur_stream);
1407     }
1408  the_end:
1409     av_free(frame);
1410     return 0;
1411 }
1412
1413 static int subtitle_thread(void *arg)
1414 {
1415     VideoState *is = arg;
1416     SubPicture *sp;
1417     AVPacket pkt1, *pkt = &pkt1;
1418     int len1, got_subtitle;
1419     double pts;
1420     int i, j;
1421     int r, g, b, y, u, v, a;
1422
1423     for(;;) {
1424         while (is->paused && !is->subtitleq.abort_request) {
1425             SDL_Delay(10);
1426         }
1427         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1428             break;
1429
1430         if(pkt->data == flush_pkt.data){
1431             avcodec_flush_buffers(is->subtitle_st->codec);
1432             continue;
1433         }
1434         SDL_LockMutex(is->subpq_mutex);
1435         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1436                !is->subtitleq.abort_request) {
1437             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1438         }
1439         SDL_UnlockMutex(is->subpq_mutex);
1440
1441         if (is->subtitleq.abort_request)
1442             goto the_end;
1443
1444         sp = &is->subpq[is->subpq_windex];
1445
1446        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1447            this packet, if any */
1448         pts = 0;
1449         if (pkt->pts != AV_NOPTS_VALUE)
1450             pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1451
1452         len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1453                                     &sp->sub, &got_subtitle,
1454                                     pkt);
1455 //            if (len1 < 0)
1456 //                break;
1457         if (got_subtitle && sp->sub.format == 0) {
1458             sp->pts = pts;
1459
1460             for (i = 0; i < sp->sub.num_rects; i++)
1461             {
1462                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1463                 {
1464                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1465                     y = RGB_TO_Y_CCIR(r, g, b);
1466                     u = RGB_TO_U_CCIR(r, g, b, 0);
1467                     v = RGB_TO_V_CCIR(r, g, b, 0);
1468                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1469                 }
1470             }
1471
1472             /* now we can update the picture count */
1473             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1474                 is->subpq_windex = 0;
1475             SDL_LockMutex(is->subpq_mutex);
1476             is->subpq_size++;
1477             SDL_UnlockMutex(is->subpq_mutex);
1478         }
1479         av_free_packet(pkt);
1480 //        if (step)
1481 //            if (cur_stream)
1482 //                stream_pause(cur_stream);
1483     }
1484  the_end:
1485     return 0;
1486 }
1487
1488 /* copy samples for viewing in editor window */
1489 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1490 {
1491     int size, len, channels;
1492
1493     channels = is->audio_st->codec->channels;
1494
1495     size = samples_size / sizeof(short);
1496     while (size > 0) {
1497         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1498         if (len > size)
1499             len = size;
1500         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1501         samples += len;
1502         is->sample_array_index += len;
1503         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1504             is->sample_array_index = 0;
1505         size -= len;
1506     }
1507 }
1508
1509 /* return the new audio buffer size (samples can be added or deleted
1510    to get better sync if video or external master clock) */
1511 static int synchronize_audio(VideoState *is, short *samples,
1512                              int samples_size1, double pts)
1513 {
1514     int n, samples_size;
1515     double ref_clock;
1516
1517     n = 2 * is->audio_st->codec->channels;
1518     samples_size = samples_size1;
1519
1520     /* if not master, then we try to remove or add samples to correct the clock */
1521     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1522          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1523         double diff, avg_diff;
1524         int wanted_size, min_size, max_size, nb_samples;
1525
1526         ref_clock = get_master_clock(is);
1527         diff = get_audio_clock(is) - ref_clock;
1528
1529         if (diff < AV_NOSYNC_THRESHOLD) {
1530             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1531             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1532                 /* not enough measures to have a correct estimate */
1533                 is->audio_diff_avg_count++;
1534             } else {
1535                 /* estimate the A-V difference */
1536                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1537
1538                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1539                     wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1540                     nb_samples = samples_size / n;
1541
1542                     min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1543                     max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1544                     if (wanted_size < min_size)
1545                         wanted_size = min_size;
1546                     else if (wanted_size > max_size)
1547                         wanted_size = max_size;
1548
1549                     /* add or remove samples to correction the synchro */
1550                     if (wanted_size < samples_size) {
1551                         /* remove samples */
1552                         samples_size = wanted_size;
1553                     } else if (wanted_size > samples_size) {
1554                         uint8_t *samples_end, *q;
1555                         int nb;
1556
1557                         /* add samples */
1558                         nb = (samples_size - wanted_size);
1559                         samples_end = (uint8_t *)samples + samples_size - n;
1560                         q = samples_end + n;
1561                         while (nb > 0) {
1562                             memcpy(q, samples_end, n);
1563                             q += n;
1564                             nb -= n;
1565                         }
1566                         samples_size = wanted_size;
1567                     }
1568                 }
1569 #if 0
1570                 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1571                        diff, avg_diff, samples_size - samples_size1,
1572                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
1573 #endif
1574             }
1575         } else {
1576             /* too big difference : may be initial PTS errors, so
1577                reset A-V filter */
1578             is->audio_diff_avg_count = 0;
1579             is->audio_diff_cum = 0;
1580         }
1581     }
1582
1583     return samples_size;
1584 }
1585
1586 /* decode one audio frame and returns its uncompressed size */
1587 static int audio_decode_frame(VideoState *is, double *pts_ptr)
1588 {
1589     AVPacket *pkt_temp = &is->audio_pkt_temp;
1590     AVPacket *pkt = &is->audio_pkt;
1591     AVCodecContext *dec= is->audio_st->codec;
1592     int n, len1, data_size;
1593     double pts;
1594
1595     for(;;) {
1596         /* NOTE: the audio packet can contain several frames */
1597         while (pkt_temp->size > 0) {
1598             data_size = sizeof(is->audio_buf1);
1599             len1 = avcodec_decode_audio3(dec,
1600                                         (int16_t *)is->audio_buf1, &data_size,
1601                                         pkt_temp);
1602             if (len1 < 0) {
1603                 /* if error, we skip the frame */
1604                 pkt_temp->size = 0;
1605                 break;
1606             }
1607
1608             pkt_temp->data += len1;
1609             pkt_temp->size -= len1;
1610             if (data_size <= 0)
1611                 continue;
1612
1613             if (dec->sample_fmt != is->audio_src_fmt) {
1614                 if (is->reformat_ctx)
1615                     av_audio_convert_free(is->reformat_ctx);
1616                 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1617                                                          dec->sample_fmt, 1, NULL, 0);
1618                 if (!is->reformat_ctx) {
1619                     fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1620                         avcodec_get_sample_fmt_name(dec->sample_fmt),
1621                         avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1622                         break;
1623                 }
1624                 is->audio_src_fmt= dec->sample_fmt;
1625             }
1626
1627             if (is->reformat_ctx) {
1628                 const void *ibuf[6]= {is->audio_buf1};
1629                 void *obuf[6]= {is->audio_buf2};
1630                 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1631                 int ostride[6]= {2};
1632                 int len= data_size/istride[0];
1633                 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1634                     printf("av_audio_convert() failed\n");
1635                     break;
1636                 }
1637                 is->audio_buf= is->audio_buf2;
1638                 /* FIXME: existing code assume that data_size equals framesize*channels*2
1639                           remove this legacy cruft */
1640                 data_size= len*2;
1641             }else{
1642                 is->audio_buf= is->audio_buf1;
1643             }
1644
1645             /* if no pts, then compute it */
1646             pts = is->audio_clock;
1647             *pts_ptr = pts;
1648             n = 2 * dec->channels;
1649             is->audio_clock += (double)data_size /
1650                 (double)(n * dec->sample_rate);
1651 #if defined(DEBUG_SYNC)
1652             {
1653                 static double last_clock;
1654                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1655                        is->audio_clock - last_clock,
1656                        is->audio_clock, pts);
1657                 last_clock = is->audio_clock;
1658             }
1659 #endif
1660             return data_size;
1661         }
1662
1663         /* free the current packet */
1664         if (pkt->data)
1665             av_free_packet(pkt);
1666
1667         if (is->paused || is->audioq.abort_request) {
1668             return -1;
1669         }
1670
1671         /* read next packet */
1672         if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1673             return -1;
1674         if(pkt->data == flush_pkt.data){
1675             avcodec_flush_buffers(dec);
1676             continue;
1677         }
1678
1679         pkt_temp->data = pkt->data;
1680         pkt_temp->size = pkt->size;
1681
1682         /* if update the audio clock with the pts */
1683         if (pkt->pts != AV_NOPTS_VALUE) {
1684             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1685         }
1686     }
1687 }
1688
1689 /* get the current audio output buffer size, in samples. With SDL, we
1690    cannot have a precise information */
1691 static int audio_write_get_buf_size(VideoState *is)
1692 {
1693     return is->audio_buf_size - is->audio_buf_index;
1694 }
1695
1696
1697 /* prepare a new audio buffer */
1698 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1699 {
1700     VideoState *is = opaque;
1701     int audio_size, len1;
1702     double pts;
1703
1704     audio_callback_time = av_gettime();
1705
1706     while (len > 0) {
1707         if (is->audio_buf_index >= is->audio_buf_size) {
1708            audio_size = audio_decode_frame(is, &pts);
1709            if (audio_size < 0) {
1710                 /* if error, just output silence */
1711                is->audio_buf = is->audio_buf1;
1712                is->audio_buf_size = 1024;
1713                memset(is->audio_buf, 0, is->audio_buf_size);
1714            } else {
1715                if (is->show_audio)
1716                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1717                audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1718                                               pts);
1719                is->audio_buf_size = audio_size;
1720            }
1721            is->audio_buf_index = 0;
1722         }
1723         len1 = is->audio_buf_size - is->audio_buf_index;
1724         if (len1 > len)
1725             len1 = len;
1726         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1727         len -= len1;
1728         stream += len1;
1729         is->audio_buf_index += len1;
1730     }
1731 }
1732
1733 /* open a given stream. Return 0 if OK */
1734 static int stream_component_open(VideoState *is, int stream_index)
1735 {
1736     AVFormatContext *ic = is->ic;
1737     AVCodecContext *enc;
1738     AVCodec *codec;
1739     SDL_AudioSpec wanted_spec, spec;
1740
1741     if (stream_index < 0 || stream_index >= ic->nb_streams)
1742         return -1;
1743     enc = ic->streams[stream_index]->codec;
1744
1745     /* prepare audio output */
1746     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1747         if (enc->channels > 0) {
1748             enc->request_channels = FFMIN(2, enc->channels);
1749         } else {
1750             enc->request_channels = 2;
1751         }
1752     }
1753
1754     codec = avcodec_find_decoder(enc->codec_id);
1755     enc->debug_mv = debug_mv;
1756     enc->debug = debug;
1757     enc->workaround_bugs = workaround_bugs;
1758     enc->lowres = lowres;
1759     if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1760     enc->idct_algo= idct;
1761     if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1762     enc->skip_frame= skip_frame;
1763     enc->skip_idct= skip_idct;
1764     enc->skip_loop_filter= skip_loop_filter;
1765     enc->error_recognition= error_recognition;
1766     enc->error_concealment= error_concealment;
1767     avcodec_thread_init(enc, thread_count);
1768
1769     set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1770
1771     if (!codec ||
1772         avcodec_open(enc, codec) < 0)
1773         return -1;
1774
1775     /* prepare audio output */
1776     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1777         wanted_spec.freq = enc->sample_rate;
1778         wanted_spec.format = AUDIO_S16SYS;
1779         wanted_spec.channels = enc->channels;
1780         wanted_spec.silence = 0;
1781         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1782         wanted_spec.callback = sdl_audio_callback;
1783         wanted_spec.userdata = is;
1784         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1785             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1786             return -1;
1787         }
1788         is->audio_hw_buf_size = spec.size;
1789         is->audio_src_fmt= SAMPLE_FMT_S16;
1790     }
1791
1792     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1793     switch(enc->codec_type) {
1794     case CODEC_TYPE_AUDIO:
1795         is->audio_stream = stream_index;
1796         is->audio_st = ic->streams[stream_index];
1797         is->audio_buf_size = 0;
1798         is->audio_buf_index = 0;
1799
1800         /* init averaging filter */
1801         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1802         is->audio_diff_avg_count = 0;
1803         /* since we do not have a precise anough audio fifo fullness,
1804            we correct audio sync only if larger than this threshold */
1805         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1806
1807         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1808         packet_queue_init(&is->audioq);
1809         SDL_PauseAudio(0);
1810         break;
1811     case CODEC_TYPE_VIDEO:
1812         is->video_stream = stream_index;
1813         is->video_st = ic->streams[stream_index];
1814
1815         is->frame_last_delay = 40e-3;
1816         is->frame_timer = (double)av_gettime() / 1000000.0;
1817 //        is->video_current_pts_time = av_gettime();
1818
1819         packet_queue_init(&is->videoq);
1820         is->video_tid = SDL_CreateThread(video_thread, is);
1821         break;
1822     case CODEC_TYPE_SUBTITLE:
1823         is->subtitle_stream = stream_index;
1824         is->subtitle_st = ic->streams[stream_index];
1825         packet_queue_init(&is->subtitleq);
1826
1827         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1828         break;
1829     default:
1830         break;
1831     }
1832     return 0;
1833 }
1834
1835 static void stream_component_close(VideoState *is, int stream_index)
1836 {
1837     AVFormatContext *ic = is->ic;
1838     AVCodecContext *enc;
1839
1840     if (stream_index < 0 || stream_index >= ic->nb_streams)
1841         return;
1842     enc = ic->streams[stream_index]->codec;
1843
1844     switch(enc->codec_type) {
1845     case CODEC_TYPE_AUDIO:
1846         packet_queue_abort(&is->audioq);
1847
1848         SDL_CloseAudio();
1849
1850         packet_queue_end(&is->audioq);
1851         if (is->reformat_ctx)
1852             av_audio_convert_free(is->reformat_ctx);
1853         break;
1854     case CODEC_TYPE_VIDEO:
1855         packet_queue_abort(&is->videoq);
1856
1857         /* note: we also signal this mutex to make sure we deblock the
1858            video thread in all cases */
1859         SDL_LockMutex(is->pictq_mutex);
1860         SDL_CondSignal(is->pictq_cond);
1861         SDL_UnlockMutex(is->pictq_mutex);
1862
1863         SDL_WaitThread(is->video_tid, NULL);
1864
1865         packet_queue_end(&is->videoq);
1866         break;
1867     case CODEC_TYPE_SUBTITLE:
1868         packet_queue_abort(&is->subtitleq);
1869
1870         /* note: we also signal this mutex to make sure we deblock the
1871            video thread in all cases */
1872         SDL_LockMutex(is->subpq_mutex);
1873         is->subtitle_stream_changed = 1;
1874
1875         SDL_CondSignal(is->subpq_cond);
1876         SDL_UnlockMutex(is->subpq_mutex);
1877
1878         SDL_WaitThread(is->subtitle_tid, NULL);
1879
1880         packet_queue_end(&is->subtitleq);
1881         break;
1882     default:
1883         break;
1884     }
1885
1886     ic->streams[stream_index]->discard = AVDISCARD_ALL;
1887     avcodec_close(enc);
1888     switch(enc->codec_type) {
1889     case CODEC_TYPE_AUDIO:
1890         is->audio_st = NULL;
1891         is->audio_stream = -1;
1892         break;
1893     case CODEC_TYPE_VIDEO:
1894         is->video_st = NULL;
1895         is->video_stream = -1;
1896         break;
1897     case CODEC_TYPE_SUBTITLE:
1898         is->subtitle_st = NULL;
1899         is->subtitle_stream = -1;
1900         break;
1901     default:
1902         break;
1903     }
1904 }
1905
1906 /* since we have only one decoding thread, we can use a global
1907    variable instead of a thread local variable */
1908 static VideoState *global_video_state;
1909
1910 static int decode_interrupt_cb(void)
1911 {
1912     return (global_video_state && global_video_state->abort_request);
1913 }
1914
1915 /* this thread gets the stream from the disk or the network */
1916 static int decode_thread(void *arg)
1917 {
1918     VideoState *is = arg;
1919     AVFormatContext *ic;
1920     int err, i, ret, video_index, audio_index, subtitle_index;
1921     AVPacket pkt1, *pkt = &pkt1;
1922     AVFormatParameters params, *ap = &params;
1923     int eof=0;
1924
1925     ic = avformat_alloc_context();
1926
1927     video_index = -1;
1928     audio_index = -1;
1929     subtitle_index = -1;
1930     is->video_stream = -1;
1931     is->audio_stream = -1;
1932     is->subtitle_stream = -1;
1933
1934     global_video_state = is;
1935     url_set_interrupt_cb(decode_interrupt_cb);
1936
1937     memset(ap, 0, sizeof(*ap));
1938
1939     ap->prealloced_context = 1;
1940     ap->width = frame_width;
1941     ap->height= frame_height;
1942     ap->time_base= (AVRational){1, 25};
1943     ap->pix_fmt = frame_pix_fmt;
1944
1945     set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
1946
1947     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1948     if (err < 0) {
1949         print_error(is->filename, err);
1950         ret = -1;
1951         goto fail;
1952     }
1953     is->ic = ic;
1954
1955     if(genpts)
1956         ic->flags |= AVFMT_FLAG_GENPTS;
1957
1958     err = av_find_stream_info(ic);
1959     if (err < 0) {
1960         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1961         ret = -1;
1962         goto fail;
1963     }
1964     if(ic->pb)
1965         ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1966
1967     /* if seeking requested, we execute it */
1968     if (start_time != AV_NOPTS_VALUE) {
1969         int64_t timestamp;
1970
1971         timestamp = start_time;
1972         /* add the stream start time */
1973         if (ic->start_time != AV_NOPTS_VALUE)
1974             timestamp += ic->start_time;
1975         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
1976         if (ret < 0) {
1977             fprintf(stderr, "%s: could not seek to position %0.3f\n",
1978                     is->filename, (double)timestamp / AV_TIME_BASE);
1979         }
1980     }
1981
1982     for(i = 0; i < ic->nb_streams; i++) {
1983         AVCodecContext *enc = ic->streams[i]->codec;
1984         ic->streams[i]->discard = AVDISCARD_ALL;
1985         switch(enc->codec_type) {
1986         case CODEC_TYPE_AUDIO:
1987             if (wanted_audio_stream-- >= 0 && !audio_disable)
1988                 audio_index = i;
1989             break;
1990         case CODEC_TYPE_VIDEO:
1991             if (wanted_video_stream-- >= 0 && !video_disable)
1992                 video_index = i;
1993             break;
1994         case CODEC_TYPE_SUBTITLE:
1995             if (wanted_subtitle_stream-- >= 0 && !video_disable)
1996                 subtitle_index = i;
1997             break;
1998         default:
1999             break;
2000         }
2001     }
2002     if (show_status) {
2003         dump_format(ic, 0, is->filename, 0);
2004     }
2005
2006     /* open the streams */
2007     if (audio_index >= 0) {
2008         stream_component_open(is, audio_index);
2009     }
2010
2011     if (video_index >= 0) {
2012         stream_component_open(is, video_index);
2013     } else {
2014         if (!display_disable)
2015             is->show_audio = 1;
2016     }
2017
2018     if (subtitle_index >= 0) {
2019         stream_component_open(is, subtitle_index);
2020     }
2021
2022     if (is->video_stream < 0 && is->audio_stream < 0) {
2023         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2024         ret = -1;
2025         goto fail;
2026     }
2027
2028     for(;;) {
2029         if (is->abort_request)
2030             break;
2031         if (is->paused != is->last_paused) {
2032             is->last_paused = is->paused;
2033             if (is->paused)
2034                 is->read_pause_return= av_read_pause(ic);
2035             else
2036                 av_read_play(ic);
2037         }
2038 #if CONFIG_RTSP_DEMUXER
2039         if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2040             /* wait 10 ms to avoid trying to get another packet */
2041             /* XXX: horrible */
2042             SDL_Delay(10);
2043             continue;
2044         }
2045 #endif
2046         if (is->seek_req) {
2047             int64_t seek_target= is->seek_pos;
2048             int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2049             int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2050 //FIXME the +-2 is due to rounding being not done in the correct direction in generation
2051 //      of the seek_pos/seek_rel variables
2052
2053             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2054             if (ret < 0) {
2055                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2056             }else{
2057                 if (is->audio_stream >= 0) {
2058                     packet_queue_flush(&is->audioq);
2059                     packet_queue_put(&is->audioq, &flush_pkt);
2060                 }
2061                 if (is->subtitle_stream >= 0) {
2062                     packet_queue_flush(&is->subtitleq);
2063                     packet_queue_put(&is->subtitleq, &flush_pkt);
2064                 }
2065                 if (is->video_stream >= 0) {
2066                     packet_queue_flush(&is->videoq);
2067                     packet_queue_put(&is->videoq, &flush_pkt);
2068                 }
2069             }
2070             is->seek_req = 0;
2071             eof= 0;
2072         }
2073
2074         /* if the queue are full, no need to read more */
2075         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2076             || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2077                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2078                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2079             /* wait 10 ms */
2080             SDL_Delay(10);
2081             continue;
2082         }
2083         if(url_feof(ic->pb) || eof) {
2084             if(is->video_stream >= 0){
2085                 av_init_packet(pkt);
2086                 pkt->data=NULL;
2087                 pkt->size=0;
2088                 pkt->stream_index= is->video_stream;
2089                 packet_queue_put(&is->videoq, pkt);
2090             }
2091             SDL_Delay(10);
2092             continue;
2093         }
2094         ret = av_read_frame(ic, pkt);
2095         if (ret < 0) {
2096             if (ret == AVERROR_EOF)
2097                 eof=1;
2098             if (url_ferror(ic->pb))
2099                 break;
2100             SDL_Delay(100); /* wait for user event */
2101             continue;
2102         }
2103         if (pkt->stream_index == is->audio_stream) {
2104             packet_queue_put(&is->audioq, pkt);
2105         } else if (pkt->stream_index == is->video_stream) {
2106             packet_queue_put(&is->videoq, pkt);
2107         } else if (pkt->stream_index == is->subtitle_stream) {
2108             packet_queue_put(&is->subtitleq, pkt);
2109         } else {
2110             av_free_packet(pkt);
2111         }
2112     }
2113     /* wait until the end */
2114     while (!is->abort_request) {
2115         SDL_Delay(100);
2116     }
2117
2118     ret = 0;
2119  fail:
2120     /* disable interrupting */
2121     global_video_state = NULL;
2122
2123     /* close each stream */
2124     if (is->audio_stream >= 0)
2125         stream_component_close(is, is->audio_stream);
2126     if (is->video_stream >= 0)
2127         stream_component_close(is, is->video_stream);
2128     if (is->subtitle_stream >= 0)
2129         stream_component_close(is, is->subtitle_stream);
2130     if (is->ic) {
2131         av_close_input_file(is->ic);
2132         is->ic = NULL; /* safety */
2133     }
2134     url_set_interrupt_cb(NULL);
2135
2136     if (ret != 0) {
2137         SDL_Event event;
2138
2139         event.type = FF_QUIT_EVENT;
2140         event.user.data1 = is;
2141         SDL_PushEvent(&event);
2142     }
2143     return 0;
2144 }
2145
2146 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2147 {
2148     VideoState *is;
2149
2150     is = av_mallocz(sizeof(VideoState));
2151     if (!is)
2152         return NULL;
2153     av_strlcpy(is->filename, filename, sizeof(is->filename));
2154     is->iformat = iformat;
2155     is->ytop = 0;
2156     is->xleft = 0;
2157
2158     /* start video display */
2159     is->pictq_mutex = SDL_CreateMutex();
2160     is->pictq_cond = SDL_CreateCond();
2161
2162     is->subpq_mutex = SDL_CreateMutex();
2163     is->subpq_cond = SDL_CreateCond();
2164
2165     /* add the refresh timer to draw the picture */
2166     schedule_refresh(is, 40);
2167
2168     is->av_sync_type = av_sync_type;
2169     is->parse_tid = SDL_CreateThread(decode_thread, is);
2170     if (!is->parse_tid) {
2171         av_free(is);
2172         return NULL;
2173     }
2174     return is;
2175 }
2176
2177 static void stream_close(VideoState *is)
2178 {
2179     VideoPicture *vp;
2180     int i;
2181     /* XXX: use a special url_shutdown call to abort parse cleanly */
2182     is->abort_request = 1;
2183     SDL_WaitThread(is->parse_tid, NULL);
2184
2185     /* free all pictures */
2186     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2187         vp = &is->pictq[i];
2188         if (vp->bmp) {
2189             SDL_FreeYUVOverlay(vp->bmp);
2190             vp->bmp = NULL;
2191         }
2192     }
2193     SDL_DestroyMutex(is->pictq_mutex);
2194     SDL_DestroyCond(is->pictq_cond);
2195     SDL_DestroyMutex(is->subpq_mutex);
2196     SDL_DestroyCond(is->subpq_cond);
2197     if (is->img_convert_ctx)
2198         sws_freeContext(is->img_convert_ctx);
2199     av_free(is);
2200 }
2201
2202 static void stream_cycle_channel(VideoState *is, int codec_type)
2203 {
2204     AVFormatContext *ic = is->ic;
2205     int start_index, stream_index;
2206     AVStream *st;
2207
2208     if (codec_type == CODEC_TYPE_VIDEO)
2209         start_index = is->video_stream;
2210     else if (codec_type == CODEC_TYPE_AUDIO)
2211         start_index = is->audio_stream;
2212     else
2213         start_index = is->subtitle_stream;
2214     if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2215         return;
2216     stream_index = start_index;
2217     for(;;) {
2218         if (++stream_index >= is->ic->nb_streams)
2219         {
2220             if (codec_type == CODEC_TYPE_SUBTITLE)
2221             {
2222                 stream_index = -1;
2223                 goto the_end;
2224             } else
2225                 stream_index = 0;
2226         }
2227         if (stream_index == start_index)
2228             return;
2229         st = ic->streams[stream_index];
2230         if (st->codec->codec_type == codec_type) {
2231             /* check that parameters are OK */
2232             switch(codec_type) {
2233             case CODEC_TYPE_AUDIO:
2234                 if (st->codec->sample_rate != 0 &&
2235                     st->codec->channels != 0)
2236                     goto the_end;
2237                 break;
2238             case CODEC_TYPE_VIDEO:
2239             case CODEC_TYPE_SUBTITLE:
2240                 goto the_end;
2241             default:
2242                 break;
2243             }
2244         }
2245     }
2246  the_end:
2247     stream_component_close(is, start_index);
2248     stream_component_open(is, stream_index);
2249 }
2250
2251
2252 static void toggle_full_screen(void)
2253 {
2254     is_full_screen = !is_full_screen;
2255     if (!fs_screen_width) {
2256         /* use default SDL method */
2257 //        SDL_WM_ToggleFullScreen(screen);
2258     }
2259     video_open(cur_stream);
2260 }
2261
2262 static void toggle_pause(void)
2263 {
2264     if (cur_stream)
2265         stream_pause(cur_stream);
2266     step = 0;
2267 }
2268
2269 static void step_to_next_frame(void)
2270 {
2271     if (cur_stream) {
2272         /* if the stream is paused unpause it, then step */
2273         if (cur_stream->paused)
2274             stream_pause(cur_stream);
2275     }
2276     step = 1;
2277 }
2278
2279 static void do_exit(void)
2280 {
2281     int i;
2282     if (cur_stream) {
2283         stream_close(cur_stream);
2284         cur_stream = NULL;
2285     }
2286     for (i = 0; i < CODEC_TYPE_NB; i++)
2287         av_free(avcodec_opts[i]);
2288     av_free(avformat_opts);
2289     av_free(sws_opts);
2290     if (show_status)
2291         printf("\n");
2292     SDL_Quit();
2293     exit(0);
2294 }
2295
2296 static void toggle_audio_display(void)
2297 {
2298     if (cur_stream) {
2299         cur_stream->show_audio = !cur_stream->show_audio;
2300     }
2301 }
2302
2303 /* handle an event sent by the GUI */
2304 static void event_loop(void)
2305 {
2306     SDL_Event event;
2307     double incr, pos, frac;
2308
2309     for(;;) {
2310         SDL_WaitEvent(&event);
2311         switch(event.type) {
2312         case SDL_KEYDOWN:
2313             switch(event.key.keysym.sym) {
2314             case SDLK_ESCAPE:
2315             case SDLK_q:
2316                 do_exit();
2317                 break;
2318             case SDLK_f:
2319                 toggle_full_screen();
2320                 break;
2321             case SDLK_p:
2322             case SDLK_SPACE:
2323                 toggle_pause();
2324                 break;
2325             case SDLK_s: //S: Step to next frame
2326                 step_to_next_frame();
2327                 break;
2328             case SDLK_a:
2329                 if (cur_stream)
2330                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2331                 break;
2332             case SDLK_v:
2333                 if (cur_stream)
2334                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2335                 break;
2336             case SDLK_t:
2337                 if (cur_stream)
2338                     stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2339                 break;
2340             case SDLK_w:
2341                 toggle_audio_display();
2342                 break;
2343             case SDLK_LEFT:
2344                 incr = -10.0;
2345                 goto do_seek;
2346             case SDLK_RIGHT:
2347                 incr = 10.0;
2348                 goto do_seek;
2349             case SDLK_UP:
2350                 incr = 60.0;
2351                 goto do_seek;
2352             case SDLK_DOWN:
2353                 incr = -60.0;
2354             do_seek:
2355                 if (cur_stream) {
2356                     if (seek_by_bytes) {
2357                         pos = url_ftell(cur_stream->ic->pb);
2358                         if (cur_stream->ic->bit_rate)
2359                             incr *= cur_stream->ic->bit_rate / 60.0;
2360                         else
2361                             incr *= 180000.0;
2362                         pos += incr;
2363                         stream_seek(cur_stream, pos, incr, 1);
2364                     } else {
2365                         pos = get_master_clock(cur_stream);
2366                         pos += incr;
2367                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2368                     }
2369                 }
2370                 break;
2371             default:
2372                 break;
2373             }
2374             break;
2375         case SDL_MOUSEBUTTONDOWN:
2376             if (cur_stream) {
2377                 if(seek_by_bytes || cur_stream->ic->duration<=0){
2378                     uint64_t size=  url_fsize(cur_stream->ic->pb);
2379                     stream_seek(cur_stream, size*(double)event.button.x/(double)cur_stream->width, 0, 1);
2380                 }else{
2381                     int64_t ts;
2382                     int ns, hh, mm, ss;
2383                     int tns, thh, tmm, tss;
2384                     tns = cur_stream->ic->duration/1000000LL;
2385                     thh = tns/3600;
2386                     tmm = (tns%3600)/60;
2387                     tss = (tns%60);
2388                     frac = (double)event.button.x/(double)cur_stream->width;
2389                     ns = frac*tns;
2390                     hh = ns/3600;
2391                     mm = (ns%3600)/60;
2392                     ss = (ns%60);
2393                     fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2394                             hh, mm, ss, thh, tmm, tss);
2395                     ts = frac*cur_stream->ic->duration;
2396                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2397                         ts += cur_stream->ic->start_time;
2398                     stream_seek(cur_stream, ts, 0, 0);
2399                 }
2400             }
2401             break;
2402         case SDL_VIDEORESIZE:
2403             if (cur_stream) {
2404                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2405                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2406                 screen_width = cur_stream->width = event.resize.w;
2407                 screen_height= cur_stream->height= event.resize.h;
2408             }
2409             break;
2410         case SDL_QUIT:
2411         case FF_QUIT_EVENT:
2412             do_exit();
2413             break;
2414         case FF_ALLOC_EVENT:
2415             video_open(event.user.data1);
2416             alloc_picture(event.user.data1);
2417             break;
2418         case FF_REFRESH_EVENT:
2419             video_refresh_timer(event.user.data1);
2420             break;
2421         default:
2422             break;
2423         }
2424     }
2425 }
2426
2427 static void opt_frame_size(const char *arg)
2428 {
2429     if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2430         fprintf(stderr, "Incorrect frame size\n");
2431         exit(1);
2432     }
2433     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2434         fprintf(stderr, "Frame size must be a multiple of 2\n");
2435         exit(1);
2436     }
2437 }
2438
2439 static int opt_width(const char *opt, const char *arg)
2440 {
2441     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2442     return 0;
2443 }
2444
2445 static int opt_height(const char *opt, const char *arg)
2446 {
2447     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2448     return 0;
2449 }
2450
2451 static void opt_format(const char *arg)
2452 {
2453     file_iformat = av_find_input_format(arg);
2454     if (!file_iformat) {
2455         fprintf(stderr, "Unknown input format: %s\n", arg);
2456         exit(1);
2457     }
2458 }
2459
2460 static void opt_frame_pix_fmt(const char *arg)
2461 {
2462     frame_pix_fmt = av_get_pix_fmt(arg);
2463 }
2464
2465 static int opt_sync(const char *opt, const char *arg)
2466 {
2467     if (!strcmp(arg, "audio"))
2468         av_sync_type = AV_SYNC_AUDIO_MASTER;
2469     else if (!strcmp(arg, "video"))
2470         av_sync_type = AV_SYNC_VIDEO_MASTER;
2471     else if (!strcmp(arg, "ext"))
2472         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2473     else {
2474         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2475         exit(1);
2476     }
2477     return 0;
2478 }
2479
2480 static int opt_seek(const char *opt, const char *arg)
2481 {
2482     start_time = parse_time_or_die(opt, arg, 1);
2483     return 0;
2484 }
2485
2486 static int opt_debug(const char *opt, const char *arg)
2487 {
2488     av_log_set_level(99);
2489     debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2490     return 0;
2491 }
2492
2493 static int opt_vismv(const char *opt, const char *arg)
2494 {
2495     debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2496     return 0;
2497 }
2498
2499 static int opt_thread_count(const char *opt, const char *arg)
2500 {
2501     thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2502 #if !HAVE_THREADS
2503     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2504 #endif
2505     return 0;
2506 }
2507
2508 static const OptionDef options[] = {
2509 #include "cmdutils_common_opts.h"
2510     { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2511     { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2512     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2513     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2514     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2515     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2516     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2517     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2518     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
2519     { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2520     { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2521     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2522     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2523     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2524     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2525     { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2526     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2527     { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2528     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2529     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2530     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2531     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2532     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2533     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2534     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2535     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2536     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2537     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2538     { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2539     { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2540     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2541     { NULL, },
2542 };
2543
2544 static void show_usage(void)
2545 {
2546     printf("Simple media player\n");
2547     printf("usage: ffplay [options] input_file\n");
2548     printf("\n");
2549 }
2550
2551 static void show_help(void)
2552 {
2553     show_usage();
2554     show_help_options(options, "Main options:\n",
2555                       OPT_EXPERT, 0);
2556     show_help_options(options, "\nAdvanced options:\n",
2557                       OPT_EXPERT, OPT_EXPERT);
2558     printf("\nWhile playing:\n"
2559            "q, ESC              quit\n"
2560            "f                   toggle full screen\n"
2561            "p, SPC              pause\n"
2562            "a                   cycle audio channel\n"
2563            "v                   cycle video channel\n"
2564            "t                   cycle subtitle channel\n"
2565            "w                   show audio waves\n"
2566            "left/right          seek backward/forward 10 seconds\n"
2567            "down/up             seek backward/forward 1 minute\n"
2568            "mouse click         seek to percentage in file corresponding to fraction of width\n"
2569            );
2570 }
2571
2572 static void opt_input_file(const char *filename)
2573 {
2574     if (!strcmp(filename, "-"))
2575         filename = "pipe:";
2576     input_filename = filename;
2577 }
2578
2579 /* Called from the main */
2580 int main(int argc, char **argv)
2581 {
2582     int flags, i;
2583
2584     /* register all codecs, demux and protocols */
2585     avcodec_register_all();
2586     avdevice_register_all();
2587     av_register_all();
2588
2589     for(i=0; i<CODEC_TYPE_NB; i++){
2590         avcodec_opts[i]= avcodec_alloc_context2(i);
2591     }
2592     avformat_opts = avformat_alloc_context();
2593     sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2594
2595     show_banner();
2596
2597     parse_options(argc, argv, options, opt_input_file);
2598
2599     if (!input_filename) {
2600         show_usage();
2601         fprintf(stderr, "An input file must be specified\n");
2602         fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2603         exit(1);
2604     }
2605
2606     if (display_disable) {
2607         video_disable = 1;
2608     }
2609     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2610 #if !defined(__MINGW32__) && !defined(__APPLE__)
2611     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2612 #endif
2613     if (SDL_Init (flags)) {
2614         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2615         exit(1);
2616     }
2617
2618     if (!display_disable) {
2619 #if HAVE_SDL_VIDEO_SIZE
2620         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2621         fs_screen_width = vi->current_w;
2622         fs_screen_height = vi->current_h;
2623 #endif
2624     }
2625
2626     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2627     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2628     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2629     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2630
2631     av_init_packet(&flush_pkt);
2632     flush_pkt.data= "FLUSH";
2633
2634     cur_stream = stream_open(input_filename, file_iformat);
2635
2636     event_loop();
2637
2638     /* never returns */
2639
2640     return 0;
2641 }