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