8517e80767970796e054712822e31ae28148e9b5
[ffmpeg.git] / ffplay.c
1 /*
2  * FFplay : Simple Media Player based on the ffmpeg libraries
3  * Copyright (c) 2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "config.h"
23 #include <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             continue;
1366         }
1367
1368         /* NOTE: ipts is the PTS of the _first_ picture beginning in
1369            this packet, if any */
1370         is->video_st->codec->reordered_opaque= pkt->pts;
1371         len1 = avcodec_decode_video2(is->video_st->codec,
1372                                     frame, &got_picture,
1373                                     pkt);
1374
1375         if(pkt->dts != AV_NOPTS_VALUE){
1376             is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1377             is->last_dts_for_fault_detection= pkt->dts;
1378         }
1379         if(frame->reordered_opaque != AV_NOPTS_VALUE){
1380             is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1381             is->last_pts_for_fault_detection= frame->reordered_opaque;
1382         }
1383
1384         if(   (   decoder_reorder_pts==1
1385                || decoder_reorder_pts && is->faulty_pts<is->faulty_dts
1386                || pkt->dts == AV_NOPTS_VALUE)
1387            && frame->reordered_opaque != AV_NOPTS_VALUE)
1388             pts= frame->reordered_opaque;
1389         else if(pkt->dts != AV_NOPTS_VALUE)
1390             pts= pkt->dts;
1391         else
1392             pts= 0;
1393         pts *= av_q2d(is->video_st->time_base);
1394
1395 //            if (len1 < 0)
1396 //                break;
1397         if (got_picture) {
1398             if (output_picture2(is, frame, pts) < 0)
1399                 goto the_end;
1400         }
1401         av_free_packet(pkt);
1402         if (step)
1403             if (cur_stream)
1404                 stream_pause(cur_stream);
1405     }
1406  the_end:
1407     av_free(frame);
1408     return 0;
1409 }
1410
1411 static int subtitle_thread(void *arg)
1412 {
1413     VideoState *is = arg;
1414     SubPicture *sp;
1415     AVPacket pkt1, *pkt = &pkt1;
1416     int len1, got_subtitle;
1417     double pts;
1418     int i, j;
1419     int r, g, b, y, u, v, a;
1420
1421     for(;;) {
1422         while (is->paused && !is->subtitleq.abort_request) {
1423             SDL_Delay(10);
1424         }
1425         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1426             break;
1427
1428         if(pkt->data == flush_pkt.data){
1429             avcodec_flush_buffers(is->subtitle_st->codec);
1430             continue;
1431         }
1432         SDL_LockMutex(is->subpq_mutex);
1433         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1434                !is->subtitleq.abort_request) {
1435             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1436         }
1437         SDL_UnlockMutex(is->subpq_mutex);
1438
1439         if (is->subtitleq.abort_request)
1440             goto the_end;
1441
1442         sp = &is->subpq[is->subpq_windex];
1443
1444        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1445            this packet, if any */
1446         pts = 0;
1447         if (pkt->pts != AV_NOPTS_VALUE)
1448             pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1449
1450         len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1451                                     &sp->sub, &got_subtitle,
1452                                     pkt);
1453 //            if (len1 < 0)
1454 //                break;
1455         if (got_subtitle && sp->sub.format == 0) {
1456             sp->pts = pts;
1457
1458             for (i = 0; i < sp->sub.num_rects; i++)
1459             {
1460                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1461                 {
1462                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1463                     y = RGB_TO_Y_CCIR(r, g, b);
1464                     u = RGB_TO_U_CCIR(r, g, b, 0);
1465                     v = RGB_TO_V_CCIR(r, g, b, 0);
1466                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1467                 }
1468             }
1469
1470             /* now we can update the picture count */
1471             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1472                 is->subpq_windex = 0;
1473             SDL_LockMutex(is->subpq_mutex);
1474             is->subpq_size++;
1475             SDL_UnlockMutex(is->subpq_mutex);
1476         }
1477         av_free_packet(pkt);
1478 //        if (step)
1479 //            if (cur_stream)
1480 //                stream_pause(cur_stream);
1481     }
1482  the_end:
1483     return 0;
1484 }
1485
1486 /* copy samples for viewing in editor window */
1487 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1488 {
1489     int size, len, channels;
1490
1491     channels = is->audio_st->codec->channels;
1492
1493     size = samples_size / sizeof(short);
1494     while (size > 0) {
1495         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1496         if (len > size)
1497             len = size;
1498         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1499         samples += len;
1500         is->sample_array_index += len;
1501         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1502             is->sample_array_index = 0;
1503         size -= len;
1504     }
1505 }
1506
1507 /* return the new audio buffer size (samples can be added or deleted
1508    to get better sync if video or external master clock) */
1509 static int synchronize_audio(VideoState *is, short *samples,
1510                              int samples_size1, double pts)
1511 {
1512     int n, samples_size;
1513     double ref_clock;
1514
1515     n = 2 * is->audio_st->codec->channels;
1516     samples_size = samples_size1;
1517
1518     /* if not master, then we try to remove or add samples to correct the clock */
1519     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1520          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1521         double diff, avg_diff;
1522         int wanted_size, min_size, max_size, nb_samples;
1523
1524         ref_clock = get_master_clock(is);
1525         diff = get_audio_clock(is) - ref_clock;
1526
1527         if (diff < AV_NOSYNC_THRESHOLD) {
1528             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1529             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1530                 /* not enough measures to have a correct estimate */
1531                 is->audio_diff_avg_count++;
1532             } else {
1533                 /* estimate the A-V difference */
1534                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1535
1536                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1537                     wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1538                     nb_samples = samples_size / n;
1539
1540                     min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1541                     max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1542                     if (wanted_size < min_size)
1543                         wanted_size = min_size;
1544                     else if (wanted_size > max_size)
1545                         wanted_size = max_size;
1546
1547                     /* add or remove samples to correction the synchro */
1548                     if (wanted_size < samples_size) {
1549                         /* remove samples */
1550                         samples_size = wanted_size;
1551                     } else if (wanted_size > samples_size) {
1552                         uint8_t *samples_end, *q;
1553                         int nb;
1554
1555                         /* add samples */
1556                         nb = (samples_size - wanted_size);
1557                         samples_end = (uint8_t *)samples + samples_size - n;
1558                         q = samples_end + n;
1559                         while (nb > 0) {
1560                             memcpy(q, samples_end, n);
1561                             q += n;
1562                             nb -= n;
1563                         }
1564                         samples_size = wanted_size;
1565                     }
1566                 }
1567 #if 0
1568                 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1569                        diff, avg_diff, samples_size - samples_size1,
1570                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
1571 #endif
1572             }
1573         } else {
1574             /* too big difference : may be initial PTS errors, so
1575                reset A-V filter */
1576             is->audio_diff_avg_count = 0;
1577             is->audio_diff_cum = 0;
1578         }
1579     }
1580
1581     return samples_size;
1582 }
1583
1584 /* decode one audio frame and returns its uncompressed size */
1585 static int audio_decode_frame(VideoState *is, double *pts_ptr)
1586 {
1587     AVPacket *pkt_temp = &is->audio_pkt_temp;
1588     AVPacket *pkt = &is->audio_pkt;
1589     AVCodecContext *dec= is->audio_st->codec;
1590     int n, len1, data_size;
1591     double pts;
1592
1593     for(;;) {
1594         /* NOTE: the audio packet can contain several frames */
1595         while (pkt_temp->size > 0) {
1596             data_size = sizeof(is->audio_buf1);
1597             len1 = avcodec_decode_audio3(dec,
1598                                         (int16_t *)is->audio_buf1, &data_size,
1599                                         pkt_temp);
1600             if (len1 < 0) {
1601                 /* if error, we skip the frame */
1602                 pkt_temp->size = 0;
1603                 break;
1604             }
1605
1606             pkt_temp->data += len1;
1607             pkt_temp->size -= len1;
1608             if (data_size <= 0)
1609                 continue;
1610
1611             if (dec->sample_fmt != is->audio_src_fmt) {
1612                 if (is->reformat_ctx)
1613                     av_audio_convert_free(is->reformat_ctx);
1614                 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1615                                                          dec->sample_fmt, 1, NULL, 0);
1616                 if (!is->reformat_ctx) {
1617                     fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1618                         avcodec_get_sample_fmt_name(dec->sample_fmt),
1619                         avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1620                         break;
1621                 }
1622                 is->audio_src_fmt= dec->sample_fmt;
1623             }
1624
1625             if (is->reformat_ctx) {
1626                 const void *ibuf[6]= {is->audio_buf1};
1627                 void *obuf[6]= {is->audio_buf2};
1628                 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1629                 int ostride[6]= {2};
1630                 int len= data_size/istride[0];
1631                 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1632                     printf("av_audio_convert() failed\n");
1633                     break;
1634                 }
1635                 is->audio_buf= is->audio_buf2;
1636                 /* FIXME: existing code assume that data_size equals framesize*channels*2
1637                           remove this legacy cruft */
1638                 data_size= len*2;
1639             }else{
1640                 is->audio_buf= is->audio_buf1;
1641             }
1642
1643             /* if no pts, then compute it */
1644             pts = is->audio_clock;
1645             *pts_ptr = pts;
1646             n = 2 * dec->channels;
1647             is->audio_clock += (double)data_size /
1648                 (double)(n * dec->sample_rate);
1649 #if defined(DEBUG_SYNC)
1650             {
1651                 static double last_clock;
1652                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1653                        is->audio_clock - last_clock,
1654                        is->audio_clock, pts);
1655                 last_clock = is->audio_clock;
1656             }
1657 #endif
1658             return data_size;
1659         }
1660
1661         /* free the current packet */
1662         if (pkt->data)
1663             av_free_packet(pkt);
1664
1665         if (is->paused || is->audioq.abort_request) {
1666             return -1;
1667         }
1668
1669         /* read next packet */
1670         if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1671             return -1;
1672         if(pkt->data == flush_pkt.data){
1673             avcodec_flush_buffers(dec);
1674             continue;
1675         }
1676
1677         pkt_temp->data = pkt->data;
1678         pkt_temp->size = pkt->size;
1679
1680         /* if update the audio clock with the pts */
1681         if (pkt->pts != AV_NOPTS_VALUE) {
1682             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1683         }
1684     }
1685 }
1686
1687 /* get the current audio output buffer size, in samples. With SDL, we
1688    cannot have a precise information */
1689 static int audio_write_get_buf_size(VideoState *is)
1690 {
1691     return is->audio_buf_size - is->audio_buf_index;
1692 }
1693
1694
1695 /* prepare a new audio buffer */
1696 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1697 {
1698     VideoState *is = opaque;
1699     int audio_size, len1;
1700     double pts;
1701
1702     audio_callback_time = av_gettime();
1703
1704     while (len > 0) {
1705         if (is->audio_buf_index >= is->audio_buf_size) {
1706            audio_size = audio_decode_frame(is, &pts);
1707            if (audio_size < 0) {
1708                 /* if error, just output silence */
1709                is->audio_buf = is->audio_buf1;
1710                is->audio_buf_size = 1024;
1711                memset(is->audio_buf, 0, is->audio_buf_size);
1712            } else {
1713                if (is->show_audio)
1714                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1715                audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1716                                               pts);
1717                is->audio_buf_size = audio_size;
1718            }
1719            is->audio_buf_index = 0;
1720         }
1721         len1 = is->audio_buf_size - is->audio_buf_index;
1722         if (len1 > len)
1723             len1 = len;
1724         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1725         len -= len1;
1726         stream += len1;
1727         is->audio_buf_index += len1;
1728     }
1729 }
1730
1731 /* open a given stream. Return 0 if OK */
1732 static int stream_component_open(VideoState *is, int stream_index)
1733 {
1734     AVFormatContext *ic = is->ic;
1735     AVCodecContext *enc;
1736     AVCodec *codec;
1737     SDL_AudioSpec wanted_spec, spec;
1738
1739     if (stream_index < 0 || stream_index >= ic->nb_streams)
1740         return -1;
1741     enc = ic->streams[stream_index]->codec;
1742
1743     /* prepare audio output */
1744     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1745         if (enc->channels > 0) {
1746             enc->request_channels = FFMIN(2, enc->channels);
1747         } else {
1748             enc->request_channels = 2;
1749         }
1750     }
1751
1752     codec = avcodec_find_decoder(enc->codec_id);
1753     enc->debug_mv = debug_mv;
1754     enc->debug = debug;
1755     enc->workaround_bugs = workaround_bugs;
1756     enc->lowres = lowres;
1757     if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1758     enc->idct_algo= idct;
1759     if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1760     enc->skip_frame= skip_frame;
1761     enc->skip_idct= skip_idct;
1762     enc->skip_loop_filter= skip_loop_filter;
1763     enc->error_recognition= error_recognition;
1764     enc->error_concealment= error_concealment;
1765     avcodec_thread_init(enc, thread_count);
1766
1767     set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1768
1769     if (!codec ||
1770         avcodec_open(enc, codec) < 0)
1771         return -1;
1772
1773     /* prepare audio output */
1774     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1775         wanted_spec.freq = enc->sample_rate;
1776         wanted_spec.format = AUDIO_S16SYS;
1777         wanted_spec.channels = enc->channels;
1778         wanted_spec.silence = 0;
1779         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1780         wanted_spec.callback = sdl_audio_callback;
1781         wanted_spec.userdata = is;
1782         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1783             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1784             return -1;
1785         }
1786         is->audio_hw_buf_size = spec.size;
1787         is->audio_src_fmt= SAMPLE_FMT_S16;
1788     }
1789
1790     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1791     switch(enc->codec_type) {
1792     case CODEC_TYPE_AUDIO:
1793         is->audio_stream = stream_index;
1794         is->audio_st = ic->streams[stream_index];
1795         is->audio_buf_size = 0;
1796         is->audio_buf_index = 0;
1797
1798         /* init averaging filter */
1799         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1800         is->audio_diff_avg_count = 0;
1801         /* since we do not have a precise anough audio fifo fullness,
1802            we correct audio sync only if larger than this threshold */
1803         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1804
1805         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1806         packet_queue_init(&is->audioq);
1807         SDL_PauseAudio(0);
1808         break;
1809     case CODEC_TYPE_VIDEO:
1810         is->video_stream = stream_index;
1811         is->video_st = ic->streams[stream_index];
1812
1813         is->frame_last_delay = 40e-3;
1814         is->frame_timer = (double)av_gettime() / 1000000.0;
1815 //        is->video_current_pts_time = av_gettime();
1816
1817         packet_queue_init(&is->videoq);
1818         is->video_tid = SDL_CreateThread(video_thread, is);
1819         break;
1820     case CODEC_TYPE_SUBTITLE:
1821         is->subtitle_stream = stream_index;
1822         is->subtitle_st = ic->streams[stream_index];
1823         packet_queue_init(&is->subtitleq);
1824
1825         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1826         break;
1827     default:
1828         break;
1829     }
1830     return 0;
1831 }
1832
1833 static void stream_component_close(VideoState *is, int stream_index)
1834 {
1835     AVFormatContext *ic = is->ic;
1836     AVCodecContext *enc;
1837
1838     if (stream_index < 0 || stream_index >= ic->nb_streams)
1839         return;
1840     enc = ic->streams[stream_index]->codec;
1841
1842     switch(enc->codec_type) {
1843     case CODEC_TYPE_AUDIO:
1844         packet_queue_abort(&is->audioq);
1845
1846         SDL_CloseAudio();
1847
1848         packet_queue_end(&is->audioq);
1849         if (is->reformat_ctx)
1850             av_audio_convert_free(is->reformat_ctx);
1851         break;
1852     case CODEC_TYPE_VIDEO:
1853         packet_queue_abort(&is->videoq);
1854
1855         /* note: we also signal this mutex to make sure we deblock the
1856            video thread in all cases */
1857         SDL_LockMutex(is->pictq_mutex);
1858         SDL_CondSignal(is->pictq_cond);
1859         SDL_UnlockMutex(is->pictq_mutex);
1860
1861         SDL_WaitThread(is->video_tid, NULL);
1862
1863         packet_queue_end(&is->videoq);
1864         break;
1865     case CODEC_TYPE_SUBTITLE:
1866         packet_queue_abort(&is->subtitleq);
1867
1868         /* note: we also signal this mutex to make sure we deblock the
1869            video thread in all cases */
1870         SDL_LockMutex(is->subpq_mutex);
1871         is->subtitle_stream_changed = 1;
1872
1873         SDL_CondSignal(is->subpq_cond);
1874         SDL_UnlockMutex(is->subpq_mutex);
1875
1876         SDL_WaitThread(is->subtitle_tid, NULL);
1877
1878         packet_queue_end(&is->subtitleq);
1879         break;
1880     default:
1881         break;
1882     }
1883
1884     ic->streams[stream_index]->discard = AVDISCARD_ALL;
1885     avcodec_close(enc);
1886     switch(enc->codec_type) {
1887     case CODEC_TYPE_AUDIO:
1888         is->audio_st = NULL;
1889         is->audio_stream = -1;
1890         break;
1891     case CODEC_TYPE_VIDEO:
1892         is->video_st = NULL;
1893         is->video_stream = -1;
1894         break;
1895     case CODEC_TYPE_SUBTITLE:
1896         is->subtitle_st = NULL;
1897         is->subtitle_stream = -1;
1898         break;
1899     default:
1900         break;
1901     }
1902 }
1903
1904 /* since we have only one decoding thread, we can use a global
1905    variable instead of a thread local variable */
1906 static VideoState *global_video_state;
1907
1908 static int decode_interrupt_cb(void)
1909 {
1910     return (global_video_state && global_video_state->abort_request);
1911 }
1912
1913 /* this thread gets the stream from the disk or the network */
1914 static int decode_thread(void *arg)
1915 {
1916     VideoState *is = arg;
1917     AVFormatContext *ic;
1918     int err, i, ret, video_index, audio_index, subtitle_index;
1919     AVPacket pkt1, *pkt = &pkt1;
1920     AVFormatParameters params, *ap = &params;
1921     int eof=0;
1922
1923     ic = avformat_alloc_context();
1924
1925     video_index = -1;
1926     audio_index = -1;
1927     subtitle_index = -1;
1928     is->video_stream = -1;
1929     is->audio_stream = -1;
1930     is->subtitle_stream = -1;
1931
1932     global_video_state = is;
1933     url_set_interrupt_cb(decode_interrupt_cb);
1934
1935     memset(ap, 0, sizeof(*ap));
1936
1937     ap->prealloced_context = 1;
1938     ap->width = frame_width;
1939     ap->height= frame_height;
1940     ap->time_base= (AVRational){1, 25};
1941     ap->pix_fmt = frame_pix_fmt;
1942
1943     set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
1944
1945     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1946     if (err < 0) {
1947         print_error(is->filename, err);
1948         ret = -1;
1949         goto fail;
1950     }
1951     is->ic = ic;
1952
1953     if(genpts)
1954         ic->flags |= AVFMT_FLAG_GENPTS;
1955
1956     err = av_find_stream_info(ic);
1957     if (err < 0) {
1958         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1959         ret = -1;
1960         goto fail;
1961     }
1962     if(ic->pb)
1963         ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1964
1965     /* if seeking requested, we execute it */
1966     if (start_time != AV_NOPTS_VALUE) {
1967         int64_t timestamp;
1968
1969         timestamp = start_time;
1970         /* add the stream start time */
1971         if (ic->start_time != AV_NOPTS_VALUE)
1972             timestamp += ic->start_time;
1973         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
1974         if (ret < 0) {
1975             fprintf(stderr, "%s: could not seek to position %0.3f\n",
1976                     is->filename, (double)timestamp / AV_TIME_BASE);
1977         }
1978     }
1979
1980     for(i = 0; i < ic->nb_streams; i++) {
1981         AVCodecContext *enc = ic->streams[i]->codec;
1982         ic->streams[i]->discard = AVDISCARD_ALL;
1983         switch(enc->codec_type) {
1984         case CODEC_TYPE_AUDIO:
1985             if (wanted_audio_stream-- >= 0 && !audio_disable)
1986                 audio_index = i;
1987             break;
1988         case CODEC_TYPE_VIDEO:
1989             if (wanted_video_stream-- >= 0 && !video_disable)
1990                 video_index = i;
1991             break;
1992         case CODEC_TYPE_SUBTITLE:
1993             if (wanted_subtitle_stream-- >= 0 && !video_disable)
1994                 subtitle_index = i;
1995             break;
1996         default:
1997             break;
1998         }
1999     }
2000     if (show_status) {
2001         dump_format(ic, 0, is->filename, 0);
2002     }
2003
2004     /* open the streams */
2005     if (audio_index >= 0) {
2006         stream_component_open(is, audio_index);
2007     }
2008
2009     if (video_index >= 0) {
2010         stream_component_open(is, video_index);
2011     } else {
2012         if (!display_disable)
2013             is->show_audio = 1;
2014     }
2015
2016     if (subtitle_index >= 0) {
2017         stream_component_open(is, subtitle_index);
2018     }
2019
2020     if (is->video_stream < 0 && is->audio_stream < 0) {
2021         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2022         ret = -1;
2023         goto fail;
2024     }
2025
2026     for(;;) {
2027         if (is->abort_request)
2028             break;
2029         if (is->paused != is->last_paused) {
2030             is->last_paused = is->paused;
2031             if (is->paused)
2032                 is->read_pause_return= av_read_pause(ic);
2033             else
2034                 av_read_play(ic);
2035         }
2036 #if CONFIG_RTSP_DEMUXER
2037         if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2038             /* wait 10 ms to avoid trying to get another packet */
2039             /* XXX: horrible */
2040             SDL_Delay(10);
2041             continue;
2042         }
2043 #endif
2044         if (is->seek_req) {
2045             int64_t seek_target= is->seek_pos;
2046             int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2047             int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2048 //FIXME the +-2 is due to rounding being not done in the correct direction in generation
2049 //      of the seek_pos/seek_rel variables
2050
2051             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2052             if (ret < 0) {
2053                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2054             }else{
2055                 if (is->audio_stream >= 0) {
2056                     packet_queue_flush(&is->audioq);
2057                     packet_queue_put(&is->audioq, &flush_pkt);
2058                 }
2059                 if (is->subtitle_stream >= 0) {
2060                     packet_queue_flush(&is->subtitleq);
2061                     packet_queue_put(&is->subtitleq, &flush_pkt);
2062                 }
2063                 if (is->video_stream >= 0) {
2064                     packet_queue_flush(&is->videoq);
2065                     packet_queue_put(&is->videoq, &flush_pkt);
2066                 }
2067             }
2068             is->seek_req = 0;
2069             eof= 0;
2070         }
2071
2072         /* if the queue are full, no need to read more */
2073         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2074             || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2075                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2076                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2077             /* wait 10 ms */
2078             SDL_Delay(10);
2079             continue;
2080         }
2081         if(url_feof(ic->pb) || eof) {
2082             if(is->video_stream >= 0){
2083                 av_init_packet(pkt);
2084                 pkt->data=NULL;
2085                 pkt->size=0;
2086                 pkt->stream_index= is->video_stream;
2087                 packet_queue_put(&is->videoq, pkt);
2088             }
2089             SDL_Delay(10);
2090             continue;
2091         }
2092         ret = av_read_frame(ic, pkt);
2093         if (ret < 0) {
2094             if (ret == AVERROR_EOF)
2095                 eof=1;
2096             if (url_ferror(ic->pb))
2097                 break;
2098             SDL_Delay(100); /* wait for user event */
2099             continue;
2100         }
2101         if (pkt->stream_index == is->audio_stream) {
2102             packet_queue_put(&is->audioq, pkt);
2103         } else if (pkt->stream_index == is->video_stream) {
2104             packet_queue_put(&is->videoq, pkt);
2105         } else if (pkt->stream_index == is->subtitle_stream) {
2106             packet_queue_put(&is->subtitleq, pkt);
2107         } else {
2108             av_free_packet(pkt);
2109         }
2110     }
2111     /* wait until the end */
2112     while (!is->abort_request) {
2113         SDL_Delay(100);
2114     }
2115
2116     ret = 0;
2117  fail:
2118     /* disable interrupting */
2119     global_video_state = NULL;
2120
2121     /* close each stream */
2122     if (is->audio_stream >= 0)
2123         stream_component_close(is, is->audio_stream);
2124     if (is->video_stream >= 0)
2125         stream_component_close(is, is->video_stream);
2126     if (is->subtitle_stream >= 0)
2127         stream_component_close(is, is->subtitle_stream);
2128     if (is->ic) {
2129         av_close_input_file(is->ic);
2130         is->ic = NULL; /* safety */
2131     }
2132     url_set_interrupt_cb(NULL);
2133
2134     if (ret != 0) {
2135         SDL_Event event;
2136
2137         event.type = FF_QUIT_EVENT;
2138         event.user.data1 = is;
2139         SDL_PushEvent(&event);
2140     }
2141     return 0;
2142 }
2143
2144 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2145 {
2146     VideoState *is;
2147
2148     is = av_mallocz(sizeof(VideoState));
2149     if (!is)
2150         return NULL;
2151     av_strlcpy(is->filename, filename, sizeof(is->filename));
2152     is->iformat = iformat;
2153     is->ytop = 0;
2154     is->xleft = 0;
2155
2156     /* start video display */
2157     is->pictq_mutex = SDL_CreateMutex();
2158     is->pictq_cond = SDL_CreateCond();
2159
2160     is->subpq_mutex = SDL_CreateMutex();
2161     is->subpq_cond = SDL_CreateCond();
2162
2163     /* add the refresh timer to draw the picture */
2164     schedule_refresh(is, 40);
2165
2166     is->av_sync_type = av_sync_type;
2167     is->parse_tid = SDL_CreateThread(decode_thread, is);
2168     if (!is->parse_tid) {
2169         av_free(is);
2170         return NULL;
2171     }
2172     return is;
2173 }
2174
2175 static void stream_close(VideoState *is)
2176 {
2177     VideoPicture *vp;
2178     int i;
2179     /* XXX: use a special url_shutdown call to abort parse cleanly */
2180     is->abort_request = 1;
2181     SDL_WaitThread(is->parse_tid, NULL);
2182
2183     /* free all pictures */
2184     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2185         vp = &is->pictq[i];
2186         if (vp->bmp) {
2187             SDL_FreeYUVOverlay(vp->bmp);
2188             vp->bmp = NULL;
2189         }
2190     }
2191     SDL_DestroyMutex(is->pictq_mutex);
2192     SDL_DestroyCond(is->pictq_cond);
2193     SDL_DestroyMutex(is->subpq_mutex);
2194     SDL_DestroyCond(is->subpq_cond);
2195     if (is->img_convert_ctx)
2196         sws_freeContext(is->img_convert_ctx);
2197     av_free(is);
2198 }
2199
2200 static void stream_cycle_channel(VideoState *is, int codec_type)
2201 {
2202     AVFormatContext *ic = is->ic;
2203     int start_index, stream_index;
2204     AVStream *st;
2205
2206     if (codec_type == CODEC_TYPE_VIDEO)
2207         start_index = is->video_stream;
2208     else if (codec_type == CODEC_TYPE_AUDIO)
2209         start_index = is->audio_stream;
2210     else
2211         start_index = is->subtitle_stream;
2212     if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2213         return;
2214     stream_index = start_index;
2215     for(;;) {
2216         if (++stream_index >= is->ic->nb_streams)
2217         {
2218             if (codec_type == CODEC_TYPE_SUBTITLE)
2219             {
2220                 stream_index = -1;
2221                 goto the_end;
2222             } else
2223                 stream_index = 0;
2224         }
2225         if (stream_index == start_index)
2226             return;
2227         st = ic->streams[stream_index];
2228         if (st->codec->codec_type == codec_type) {
2229             /* check that parameters are OK */
2230             switch(codec_type) {
2231             case CODEC_TYPE_AUDIO:
2232                 if (st->codec->sample_rate != 0 &&
2233                     st->codec->channels != 0)
2234                     goto the_end;
2235                 break;
2236             case CODEC_TYPE_VIDEO:
2237             case CODEC_TYPE_SUBTITLE:
2238                 goto the_end;
2239             default:
2240                 break;
2241             }
2242         }
2243     }
2244  the_end:
2245     stream_component_close(is, start_index);
2246     stream_component_open(is, stream_index);
2247 }
2248
2249
2250 static void toggle_full_screen(void)
2251 {
2252     is_full_screen = !is_full_screen;
2253     if (!fs_screen_width) {
2254         /* use default SDL method */
2255 //        SDL_WM_ToggleFullScreen(screen);
2256     }
2257     video_open(cur_stream);
2258 }
2259
2260 static void toggle_pause(void)
2261 {
2262     if (cur_stream)
2263         stream_pause(cur_stream);
2264     step = 0;
2265 }
2266
2267 static void step_to_next_frame(void)
2268 {
2269     if (cur_stream) {
2270         /* if the stream is paused unpause it, then step */
2271         if (cur_stream->paused)
2272             stream_pause(cur_stream);
2273     }
2274     step = 1;
2275 }
2276
2277 static void do_exit(void)
2278 {
2279     int i;
2280     if (cur_stream) {
2281         stream_close(cur_stream);
2282         cur_stream = NULL;
2283     }
2284     for (i = 0; i < CODEC_TYPE_NB; i++)
2285         av_free(avcodec_opts[i]);
2286     av_free(avformat_opts);
2287     av_free(sws_opts);
2288     if (show_status)
2289         printf("\n");
2290     SDL_Quit();
2291     exit(0);
2292 }
2293
2294 static void toggle_audio_display(void)
2295 {
2296     if (cur_stream) {
2297         cur_stream->show_audio = !cur_stream->show_audio;
2298     }
2299 }
2300
2301 /* handle an event sent by the GUI */
2302 static void event_loop(void)
2303 {
2304     SDL_Event event;
2305     double incr, pos, frac;
2306
2307     for(;;) {
2308         SDL_WaitEvent(&event);
2309         switch(event.type) {
2310         case SDL_KEYDOWN:
2311             switch(event.key.keysym.sym) {
2312             case SDLK_ESCAPE:
2313             case SDLK_q:
2314                 do_exit();
2315                 break;
2316             case SDLK_f:
2317                 toggle_full_screen();
2318                 break;
2319             case SDLK_p:
2320             case SDLK_SPACE:
2321                 toggle_pause();
2322                 break;
2323             case SDLK_s: //S: Step to next frame
2324                 step_to_next_frame();
2325                 break;
2326             case SDLK_a:
2327                 if (cur_stream)
2328                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2329                 break;
2330             case SDLK_v:
2331                 if (cur_stream)
2332                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2333                 break;
2334             case SDLK_t:
2335                 if (cur_stream)
2336                     stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2337                 break;
2338             case SDLK_w:
2339                 toggle_audio_display();
2340                 break;
2341             case SDLK_LEFT:
2342                 incr = -10.0;
2343                 goto do_seek;
2344             case SDLK_RIGHT:
2345                 incr = 10.0;
2346                 goto do_seek;
2347             case SDLK_UP:
2348                 incr = 60.0;
2349                 goto do_seek;
2350             case SDLK_DOWN:
2351                 incr = -60.0;
2352             do_seek:
2353                 if (cur_stream) {
2354                     if (seek_by_bytes) {
2355                         pos = url_ftell(cur_stream->ic->pb);
2356                         if (cur_stream->ic->bit_rate)
2357                             incr *= cur_stream->ic->bit_rate / 60.0;
2358                         else
2359                             incr *= 180000.0;
2360                         pos += incr;
2361                         stream_seek(cur_stream, pos, incr, 1);
2362                     } else {
2363                         pos = get_master_clock(cur_stream);
2364                         pos += incr;
2365                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2366                     }
2367                 }
2368                 break;
2369             default:
2370                 break;
2371             }
2372             break;
2373         case SDL_MOUSEBUTTONDOWN:
2374             if (cur_stream) {
2375                 if(seek_by_bytes || cur_stream->ic->duration<=0){
2376                     uint64_t size=  url_fsize(cur_stream->ic->pb);
2377                     stream_seek(cur_stream, size*(double)event.button.x/(double)cur_stream->width, 0, 1);
2378                 }else{
2379                     int64_t ts;
2380                     int ns, hh, mm, ss;
2381                     int tns, thh, tmm, tss;
2382                     tns = cur_stream->ic->duration/1000000LL;
2383                     thh = tns/3600;
2384                     tmm = (tns%3600)/60;
2385                     tss = (tns%60);
2386                     frac = (double)event.button.x/(double)cur_stream->width;
2387                     ns = frac*tns;
2388                     hh = ns/3600;
2389                     mm = (ns%3600)/60;
2390                     ss = (ns%60);
2391                     fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2392                             hh, mm, ss, thh, tmm, tss);
2393                     ts = frac*cur_stream->ic->duration;
2394                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2395                         ts += cur_stream->ic->start_time;
2396                     stream_seek(cur_stream, ts, 0, 0);
2397                 }
2398             }
2399             break;
2400         case SDL_VIDEORESIZE:
2401             if (cur_stream) {
2402                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2403                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2404                 screen_width = cur_stream->width = event.resize.w;
2405                 screen_height= cur_stream->height= event.resize.h;
2406             }
2407             break;
2408         case SDL_QUIT:
2409         case FF_QUIT_EVENT:
2410             do_exit();
2411             break;
2412         case FF_ALLOC_EVENT:
2413             video_open(event.user.data1);
2414             alloc_picture(event.user.data1);
2415             break;
2416         case FF_REFRESH_EVENT:
2417             video_refresh_timer(event.user.data1);
2418             break;
2419         default:
2420             break;
2421         }
2422     }
2423 }
2424
2425 static void opt_frame_size(const char *arg)
2426 {
2427     if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2428         fprintf(stderr, "Incorrect frame size\n");
2429         exit(1);
2430     }
2431     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2432         fprintf(stderr, "Frame size must be a multiple of 2\n");
2433         exit(1);
2434     }
2435 }
2436
2437 static int opt_width(const char *opt, const char *arg)
2438 {
2439     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2440     return 0;
2441 }
2442
2443 static int opt_height(const char *opt, const char *arg)
2444 {
2445     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2446     return 0;
2447 }
2448
2449 static void opt_format(const char *arg)
2450 {
2451     file_iformat = av_find_input_format(arg);
2452     if (!file_iformat) {
2453         fprintf(stderr, "Unknown input format: %s\n", arg);
2454         exit(1);
2455     }
2456 }
2457
2458 static void opt_frame_pix_fmt(const char *arg)
2459 {
2460     frame_pix_fmt = av_get_pix_fmt(arg);
2461 }
2462
2463 static int opt_sync(const char *opt, const char *arg)
2464 {
2465     if (!strcmp(arg, "audio"))
2466         av_sync_type = AV_SYNC_AUDIO_MASTER;
2467     else if (!strcmp(arg, "video"))
2468         av_sync_type = AV_SYNC_VIDEO_MASTER;
2469     else if (!strcmp(arg, "ext"))
2470         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2471     else {
2472         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2473         exit(1);
2474     }
2475     return 0;
2476 }
2477
2478 static int opt_seek(const char *opt, const char *arg)
2479 {
2480     start_time = parse_time_or_die(opt, arg, 1);
2481     return 0;
2482 }
2483
2484 static int opt_debug(const char *opt, const char *arg)
2485 {
2486     av_log_set_level(99);
2487     debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2488     return 0;
2489 }
2490
2491 static int opt_vismv(const char *opt, const char *arg)
2492 {
2493     debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2494     return 0;
2495 }
2496
2497 static int opt_thread_count(const char *opt, const char *arg)
2498 {
2499     thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2500 #if !HAVE_THREADS
2501     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2502 #endif
2503     return 0;
2504 }
2505
2506 static const OptionDef options[] = {
2507 #include "cmdutils_common_opts.h"
2508     { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2509     { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2510     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2511     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2512     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2513     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2514     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2515     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2516     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
2517     { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2518     { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2519     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2520     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2521     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2522     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2523     { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2524     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2525     { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2526     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2527     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2528     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2529     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2530     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2531     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2532     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2533     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2534     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2535     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2536     { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2537     { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2538     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2539     { NULL, },
2540 };
2541
2542 static void show_usage(void)
2543 {
2544     printf("Simple media player\n");
2545     printf("usage: ffplay [options] input_file\n");
2546     printf("\n");
2547 }
2548
2549 static void show_help(void)
2550 {
2551     show_usage();
2552     show_help_options(options, "Main options:\n",
2553                       OPT_EXPERT, 0);
2554     show_help_options(options, "\nAdvanced options:\n",
2555                       OPT_EXPERT, OPT_EXPERT);
2556     printf("\nWhile playing:\n"
2557            "q, ESC              quit\n"
2558            "f                   toggle full screen\n"
2559            "p, SPC              pause\n"
2560            "a                   cycle audio channel\n"
2561            "v                   cycle video channel\n"
2562            "t                   cycle subtitle channel\n"
2563            "w                   show audio waves\n"
2564            "left/right          seek backward/forward 10 seconds\n"
2565            "down/up             seek backward/forward 1 minute\n"
2566            "mouse click         seek to percentage in file corresponding to fraction of width\n"
2567            );
2568 }
2569
2570 static void opt_input_file(const char *filename)
2571 {
2572     if (!strcmp(filename, "-"))
2573         filename = "pipe:";
2574     input_filename = filename;
2575 }
2576
2577 /* Called from the main */
2578 int main(int argc, char **argv)
2579 {
2580     int flags, i;
2581
2582     /* register all codecs, demux and protocols */
2583     avcodec_register_all();
2584     avdevice_register_all();
2585     av_register_all();
2586
2587     for(i=0; i<CODEC_TYPE_NB; i++){
2588         avcodec_opts[i]= avcodec_alloc_context2(i);
2589     }
2590     avformat_opts = avformat_alloc_context();
2591     sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2592
2593     show_banner();
2594
2595     parse_options(argc, argv, options, opt_input_file);
2596
2597     if (!input_filename) {
2598         show_usage();
2599         fprintf(stderr, "An input file must be specified\n");
2600         fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2601         exit(1);
2602     }
2603
2604     if (display_disable) {
2605         video_disable = 1;
2606     }
2607     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2608 #if !defined(__MINGW32__) && !defined(__APPLE__)
2609     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2610 #endif
2611     if (SDL_Init (flags)) {
2612         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2613         exit(1);
2614     }
2615
2616     if (!display_disable) {
2617 #if HAVE_SDL_VIDEO_SIZE
2618         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2619         fs_screen_width = vi->current_w;
2620         fs_screen_height = vi->current_h;
2621 #endif
2622     }
2623
2624     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2625     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2626     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2627     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2628
2629     av_init_packet(&flush_pkt);
2630     flush_pkt.data= "FLUSH";
2631
2632     cur_stream = stream_open(input_filename, file_iformat);
2633
2634     event_loop();
2635
2636     /* never returns */
2637
2638     return 0;
2639 }