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