]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - ffplay.c
Extract into its own function the code to compute frame delay.
[frescor/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;
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;
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     }
1018     is->frame_last_delay = delay;
1019     is->frame_last_pts = frame_current_pts;
1020
1021     /* update delay to follow master synchronisation source */
1022     if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1023          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1024         /* if video is slave, we try to correct big delays by
1025            duplicating or deleting a frame */
1026         ref_clock = get_master_clock(is);
1027         diff = frame_current_pts - ref_clock;
1028
1029         /* skip or repeat frame. We take into account the
1030            delay to compute the threshold. I still don't know
1031            if it is the best guess */
1032         sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1033         if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1034             if (diff <= -sync_threshold)
1035                 delay = 0;
1036             else if (diff >= sync_threshold)
1037                 delay = 2 * delay;
1038         }
1039     }
1040
1041     is->frame_timer += delay;
1042     /* compute the REAL delay (we need to do that to avoid
1043        long term errors */
1044     actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1045     if (actual_delay < 0.010) {
1046         /* XXX: should skip picture */
1047         actual_delay = 0.010;
1048     }
1049
1050     return actual_delay;
1051 }
1052
1053 /* called to display each frame */
1054 static void video_refresh_timer(void *opaque)
1055 {
1056     VideoState *is = opaque;
1057     VideoPicture *vp;
1058
1059     SubPicture *sp, *sp2;
1060
1061     if (is->video_st) {
1062         if (is->pictq_size == 0) {
1063             /* if no picture, need to wait */
1064             schedule_refresh(is, 1);
1065         } else {
1066             /* dequeue the picture */
1067             vp = &is->pictq[is->pictq_rindex];
1068
1069             /* update current video pts */
1070             is->video_current_pts = vp->pts;
1071             is->video_current_pts_time = av_gettime();
1072
1073             /* launch timer for next picture */
1074             schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1075
1076 #if defined(DEBUG_SYNC)
1077             printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1078                    delay, actual_delay, vp->pts, -diff);
1079 #endif
1080
1081             if(is->subtitle_st) {
1082                 if (is->subtitle_stream_changed) {
1083                     SDL_LockMutex(is->subpq_mutex);
1084
1085                     while (is->subpq_size) {
1086                         free_subpicture(&is->subpq[is->subpq_rindex]);
1087
1088                         /* update queue size and signal for next picture */
1089                         if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1090                             is->subpq_rindex = 0;
1091
1092                         is->subpq_size--;
1093                     }
1094                     is->subtitle_stream_changed = 0;
1095
1096                     SDL_CondSignal(is->subpq_cond);
1097                     SDL_UnlockMutex(is->subpq_mutex);
1098                 } else {
1099                     if (is->subpq_size > 0) {
1100                         sp = &is->subpq[is->subpq_rindex];
1101
1102                         if (is->subpq_size > 1)
1103                             sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1104                         else
1105                             sp2 = NULL;
1106
1107                         if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1108                                 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1109                         {
1110                             free_subpicture(sp);
1111
1112                             /* update queue size and signal for next picture */
1113                             if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1114                                 is->subpq_rindex = 0;
1115
1116                             SDL_LockMutex(is->subpq_mutex);
1117                             is->subpq_size--;
1118                             SDL_CondSignal(is->subpq_cond);
1119                             SDL_UnlockMutex(is->subpq_mutex);
1120                         }
1121                     }
1122                 }
1123             }
1124
1125             /* display picture */
1126             video_display(is);
1127
1128             /* update queue size and signal for next picture */
1129             if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1130                 is->pictq_rindex = 0;
1131
1132             SDL_LockMutex(is->pictq_mutex);
1133             is->pictq_size--;
1134             SDL_CondSignal(is->pictq_cond);
1135             SDL_UnlockMutex(is->pictq_mutex);
1136         }
1137     } else if (is->audio_st) {
1138         /* draw the next audio frame */
1139
1140         schedule_refresh(is, 40);
1141
1142         /* if only audio stream, then display the audio bars (better
1143            than nothing, just to test the implementation */
1144
1145         /* display picture */
1146         video_display(is);
1147     } else {
1148         schedule_refresh(is, 100);
1149     }
1150     if (show_status) {
1151         static int64_t last_time;
1152         int64_t cur_time;
1153         int aqsize, vqsize, sqsize;
1154         double av_diff;
1155
1156         cur_time = av_gettime();
1157         if (!last_time || (cur_time - last_time) >= 500 * 1000) {
1158             aqsize = 0;
1159             vqsize = 0;
1160             sqsize = 0;
1161             if (is->audio_st)
1162                 aqsize = is->audioq.size;
1163             if (is->video_st)
1164                 vqsize = is->videoq.size;
1165             if (is->subtitle_st)
1166                 sqsize = is->subtitleq.size;
1167             av_diff = 0;
1168             if (is->audio_st && is->video_st)
1169                 av_diff = get_audio_clock(is) - get_video_clock(is);
1170             printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
1171                    get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1172             fflush(stdout);
1173             last_time = cur_time;
1174         }
1175     }
1176 }
1177
1178 /* allocate a picture (needs to do that in main thread to avoid
1179    potential locking problems */
1180 static void alloc_picture(void *opaque)
1181 {
1182     VideoState *is = opaque;
1183     VideoPicture *vp;
1184
1185     vp = &is->pictq[is->pictq_windex];
1186
1187     if (vp->bmp)
1188         SDL_FreeYUVOverlay(vp->bmp);
1189
1190 #if 0
1191     /* XXX: use generic function */
1192     /* XXX: disable overlay if no hardware acceleration or if RGB format */
1193     switch(is->video_st->codec->pix_fmt) {
1194     case PIX_FMT_YUV420P:
1195     case PIX_FMT_YUV422P:
1196     case PIX_FMT_YUV444P:
1197     case PIX_FMT_YUYV422:
1198     case PIX_FMT_YUV410P:
1199     case PIX_FMT_YUV411P:
1200         is_yuv = 1;
1201         break;
1202     default:
1203         is_yuv = 0;
1204         break;
1205     }
1206 #endif
1207     vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1208                                    is->video_st->codec->height,
1209                                    SDL_YV12_OVERLAY,
1210                                    screen);
1211     vp->width = is->video_st->codec->width;
1212     vp->height = is->video_st->codec->height;
1213
1214     SDL_LockMutex(is->pictq_mutex);
1215     vp->allocated = 1;
1216     SDL_CondSignal(is->pictq_cond);
1217     SDL_UnlockMutex(is->pictq_mutex);
1218 }
1219
1220 /**
1221  *
1222  * @param pts the dts of the pkt / pts of the frame and guessed if not known
1223  */
1224 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1225 {
1226     VideoPicture *vp;
1227     int dst_pix_fmt;
1228     AVPicture pict;
1229     static struct SwsContext *img_convert_ctx;
1230
1231     /* wait until we have space to put a new picture */
1232     SDL_LockMutex(is->pictq_mutex);
1233     while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1234            !is->videoq.abort_request) {
1235         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1236     }
1237     SDL_UnlockMutex(is->pictq_mutex);
1238
1239     if (is->videoq.abort_request)
1240         return -1;
1241
1242     vp = &is->pictq[is->pictq_windex];
1243
1244     /* alloc or resize hardware picture buffer */
1245     if (!vp->bmp ||
1246         vp->width != is->video_st->codec->width ||
1247         vp->height != is->video_st->codec->height) {
1248         SDL_Event event;
1249
1250         vp->allocated = 0;
1251
1252         /* the allocation must be done in the main thread to avoid
1253            locking problems */
1254         event.type = FF_ALLOC_EVENT;
1255         event.user.data1 = is;
1256         SDL_PushEvent(&event);
1257
1258         /* wait until the picture is allocated */
1259         SDL_LockMutex(is->pictq_mutex);
1260         while (!vp->allocated && !is->videoq.abort_request) {
1261             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1262         }
1263         SDL_UnlockMutex(is->pictq_mutex);
1264
1265         if (is->videoq.abort_request)
1266             return -1;
1267     }
1268
1269     /* if the frame is not skipped, then display it */
1270     if (vp->bmp) {
1271         /* get a pointer on the bitmap */
1272         SDL_LockYUVOverlay (vp->bmp);
1273
1274         dst_pix_fmt = PIX_FMT_YUV420P;
1275         pict.data[0] = vp->bmp->pixels[0];
1276         pict.data[1] = vp->bmp->pixels[2];
1277         pict.data[2] = vp->bmp->pixels[1];
1278
1279         pict.linesize[0] = vp->bmp->pitches[0];
1280         pict.linesize[1] = vp->bmp->pitches[2];
1281         pict.linesize[2] = vp->bmp->pitches[1];
1282         sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1283         img_convert_ctx = sws_getCachedContext(img_convert_ctx,
1284             is->video_st->codec->width, is->video_st->codec->height,
1285             is->video_st->codec->pix_fmt,
1286             is->video_st->codec->width, is->video_st->codec->height,
1287             dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1288         if (img_convert_ctx == NULL) {
1289             fprintf(stderr, "Cannot initialize the conversion context\n");
1290             exit(1);
1291         }
1292         sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
1293                   0, is->video_st->codec->height, pict.data, pict.linesize);
1294         /* update the bitmap content */
1295         SDL_UnlockYUVOverlay(vp->bmp);
1296
1297         vp->pts = pts;
1298
1299         /* now we can update the picture count */
1300         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1301             is->pictq_windex = 0;
1302         SDL_LockMutex(is->pictq_mutex);
1303         is->pictq_size++;
1304         SDL_UnlockMutex(is->pictq_mutex);
1305     }
1306     return 0;
1307 }
1308
1309 /**
1310  * compute the exact PTS for the picture if it is omitted in the stream
1311  * @param pts1 the dts of the pkt / pts of the frame
1312  */
1313 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1314 {
1315     double frame_delay, pts;
1316
1317     pts = pts1;
1318
1319     if (pts != 0) {
1320         /* update video clock with pts, if present */
1321         is->video_clock = pts;
1322     } else {
1323         pts = is->video_clock;
1324     }
1325     /* update video clock for next frame */
1326     frame_delay = av_q2d(is->video_st->codec->time_base);
1327     /* for MPEG2, the frame can be repeated, so we update the
1328        clock accordingly */
1329     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1330     is->video_clock += frame_delay;
1331
1332 #if defined(DEBUG_SYNC) && 0
1333     {
1334         int ftype;
1335         if (src_frame->pict_type == FF_B_TYPE)
1336             ftype = 'B';
1337         else if (src_frame->pict_type == FF_I_TYPE)
1338             ftype = 'I';
1339         else
1340             ftype = 'P';
1341         printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1342                ftype, pts, pts1);
1343     }
1344 #endif
1345     return queue_picture(is, src_frame, pts);
1346 }
1347
1348 static int video_thread(void *arg)
1349 {
1350     VideoState *is = arg;
1351     AVPacket pkt1, *pkt = &pkt1;
1352     int len1, got_picture;
1353     AVFrame *frame= avcodec_alloc_frame();
1354     double pts;
1355
1356     for(;;) {
1357         while (is->paused && !is->videoq.abort_request) {
1358             SDL_Delay(10);
1359         }
1360         if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1361             break;
1362
1363         if(pkt->data == flush_pkt.data){
1364             avcodec_flush_buffers(is->video_st->codec);
1365             continue;
1366         }
1367
1368         /* NOTE: ipts is the PTS of the _first_ picture beginning in
1369            this packet, if any */
1370         is->video_st->codec->reordered_opaque= pkt->pts;
1371         len1 = avcodec_decode_video(is->video_st->codec,
1372                                     frame, &got_picture,
1373                                     pkt->data, pkt->size);
1374
1375         if(   (decoder_reorder_pts || pkt->dts == AV_NOPTS_VALUE)
1376            && frame->reordered_opaque != AV_NOPTS_VALUE)
1377             pts= frame->reordered_opaque;
1378         else if(pkt->dts != AV_NOPTS_VALUE)
1379             pts= pkt->dts;
1380         else
1381             pts= 0;
1382         pts *= av_q2d(is->video_st->time_base);
1383
1384 //            if (len1 < 0)
1385 //                break;
1386         if (got_picture) {
1387             if (output_picture2(is, frame, pts) < 0)
1388                 goto the_end;
1389         }
1390         av_free_packet(pkt);
1391         if (step)
1392             if (cur_stream)
1393                 stream_pause(cur_stream);
1394     }
1395  the_end:
1396     av_free(frame);
1397     return 0;
1398 }
1399
1400 static int subtitle_thread(void *arg)
1401 {
1402     VideoState *is = arg;
1403     SubPicture *sp;
1404     AVPacket pkt1, *pkt = &pkt1;
1405     int len1, got_subtitle;
1406     double pts;
1407     int i, j;
1408     int r, g, b, y, u, v, a;
1409
1410     for(;;) {
1411         while (is->paused && !is->subtitleq.abort_request) {
1412             SDL_Delay(10);
1413         }
1414         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1415             break;
1416
1417         if(pkt->data == flush_pkt.data){
1418             avcodec_flush_buffers(is->subtitle_st->codec);
1419             continue;
1420         }
1421         SDL_LockMutex(is->subpq_mutex);
1422         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1423                !is->subtitleq.abort_request) {
1424             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1425         }
1426         SDL_UnlockMutex(is->subpq_mutex);
1427
1428         if (is->subtitleq.abort_request)
1429             goto the_end;
1430
1431         sp = &is->subpq[is->subpq_windex];
1432
1433        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1434            this packet, if any */
1435         pts = 0;
1436         if (pkt->pts != AV_NOPTS_VALUE)
1437             pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1438
1439         len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
1440                                     &sp->sub, &got_subtitle,
1441                                     pkt->data, pkt->size);
1442 //            if (len1 < 0)
1443 //                break;
1444         if (got_subtitle && sp->sub.format == 0) {
1445             sp->pts = pts;
1446
1447             for (i = 0; i < sp->sub.num_rects; i++)
1448             {
1449                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1450                 {
1451                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1452                     y = RGB_TO_Y_CCIR(r, g, b);
1453                     u = RGB_TO_U_CCIR(r, g, b, 0);
1454                     v = RGB_TO_V_CCIR(r, g, b, 0);
1455                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1456                 }
1457             }
1458
1459             /* now we can update the picture count */
1460             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1461                 is->subpq_windex = 0;
1462             SDL_LockMutex(is->subpq_mutex);
1463             is->subpq_size++;
1464             SDL_UnlockMutex(is->subpq_mutex);
1465         }
1466         av_free_packet(pkt);
1467 //        if (step)
1468 //            if (cur_stream)
1469 //                stream_pause(cur_stream);
1470     }
1471  the_end:
1472     return 0;
1473 }
1474
1475 /* copy samples for viewing in editor window */
1476 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1477 {
1478     int size, len, channels;
1479
1480     channels = is->audio_st->codec->channels;
1481
1482     size = samples_size / sizeof(short);
1483     while (size > 0) {
1484         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1485         if (len > size)
1486             len = size;
1487         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1488         samples += len;
1489         is->sample_array_index += len;
1490         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1491             is->sample_array_index = 0;
1492         size -= len;
1493     }
1494 }
1495
1496 /* return the new audio buffer size (samples can be added or deleted
1497    to get better sync if video or external master clock) */
1498 static int synchronize_audio(VideoState *is, short *samples,
1499                              int samples_size1, double pts)
1500 {
1501     int n, samples_size;
1502     double ref_clock;
1503
1504     n = 2 * is->audio_st->codec->channels;
1505     samples_size = samples_size1;
1506
1507     /* if not master, then we try to remove or add samples to correct the clock */
1508     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1509          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1510         double diff, avg_diff;
1511         int wanted_size, min_size, max_size, nb_samples;
1512
1513         ref_clock = get_master_clock(is);
1514         diff = get_audio_clock(is) - ref_clock;
1515
1516         if (diff < AV_NOSYNC_THRESHOLD) {
1517             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1518             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1519                 /* not enough measures to have a correct estimate */
1520                 is->audio_diff_avg_count++;
1521             } else {
1522                 /* estimate the A-V difference */
1523                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1524
1525                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1526                     wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1527                     nb_samples = samples_size / n;
1528
1529                     min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1530                     max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1531                     if (wanted_size < min_size)
1532                         wanted_size = min_size;
1533                     else if (wanted_size > max_size)
1534                         wanted_size = max_size;
1535
1536                     /* add or remove samples to correction the synchro */
1537                     if (wanted_size < samples_size) {
1538                         /* remove samples */
1539                         samples_size = wanted_size;
1540                     } else if (wanted_size > samples_size) {
1541                         uint8_t *samples_end, *q;
1542                         int nb;
1543
1544                         /* add samples */
1545                         nb = (samples_size - wanted_size);
1546                         samples_end = (uint8_t *)samples + samples_size - n;
1547                         q = samples_end + n;
1548                         while (nb > 0) {
1549                             memcpy(q, samples_end, n);
1550                             q += n;
1551                             nb -= n;
1552                         }
1553                         samples_size = wanted_size;
1554                     }
1555                 }
1556 #if 0
1557                 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1558                        diff, avg_diff, samples_size - samples_size1,
1559                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
1560 #endif
1561             }
1562         } else {
1563             /* too big difference : may be initial PTS errors, so
1564                reset A-V filter */
1565             is->audio_diff_avg_count = 0;
1566             is->audio_diff_cum = 0;
1567         }
1568     }
1569
1570     return samples_size;
1571 }
1572
1573 /* decode one audio frame and returns its uncompressed size */
1574 static int audio_decode_frame(VideoState *is, double *pts_ptr)
1575 {
1576     AVPacket *pkt = &is->audio_pkt;
1577     AVCodecContext *dec= is->audio_st->codec;
1578     int n, len1, data_size;
1579     double pts;
1580
1581     for(;;) {
1582         /* NOTE: the audio packet can contain several frames */
1583         while (is->audio_pkt_size > 0) {
1584             data_size = sizeof(is->audio_buf1);
1585             len1 = avcodec_decode_audio2(dec,
1586                                         (int16_t *)is->audio_buf1, &data_size,
1587                                         is->audio_pkt_data, is->audio_pkt_size);
1588             if (len1 < 0) {
1589                 /* if error, we skip the frame */
1590                 is->audio_pkt_size = 0;
1591                 break;
1592             }
1593
1594             is->audio_pkt_data += len1;
1595             is->audio_pkt_size -= len1;
1596             if (data_size <= 0)
1597                 continue;
1598
1599             if (dec->sample_fmt != is->audio_src_fmt) {
1600                 if (is->reformat_ctx)
1601                     av_audio_convert_free(is->reformat_ctx);
1602                 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1603                                                          dec->sample_fmt, 1, NULL, 0);
1604                 if (!is->reformat_ctx) {
1605                     fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1606                         avcodec_get_sample_fmt_name(dec->sample_fmt),
1607                         avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1608                         break;
1609                 }
1610                 is->audio_src_fmt= dec->sample_fmt;
1611             }
1612
1613             if (is->reformat_ctx) {
1614                 const void *ibuf[6]= {is->audio_buf1};
1615                 void *obuf[6]= {is->audio_buf2};
1616                 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1617                 int ostride[6]= {2};
1618                 int len= data_size/istride[0];
1619                 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1620                     printf("av_audio_convert() failed\n");
1621                     break;
1622                 }
1623                 is->audio_buf= is->audio_buf2;
1624                 /* FIXME: existing code assume that data_size equals framesize*channels*2
1625                           remove this legacy cruft */
1626                 data_size= len*2;
1627             }else{
1628                 is->audio_buf= is->audio_buf1;
1629             }
1630
1631             /* if no pts, then compute it */
1632             pts = is->audio_clock;
1633             *pts_ptr = pts;
1634             n = 2 * dec->channels;
1635             is->audio_clock += (double)data_size /
1636                 (double)(n * dec->sample_rate);
1637 #if defined(DEBUG_SYNC)
1638             {
1639                 static double last_clock;
1640                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1641                        is->audio_clock - last_clock,
1642                        is->audio_clock, pts);
1643                 last_clock = is->audio_clock;
1644             }
1645 #endif
1646             return data_size;
1647         }
1648
1649         /* free the current packet */
1650         if (pkt->data)
1651             av_free_packet(pkt);
1652
1653         if (is->paused || is->audioq.abort_request) {
1654             return -1;
1655         }
1656
1657         /* read next packet */
1658         if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1659             return -1;
1660         if(pkt->data == flush_pkt.data){
1661             avcodec_flush_buffers(dec);
1662             continue;
1663         }
1664
1665         is->audio_pkt_data = pkt->data;
1666         is->audio_pkt_size = pkt->size;
1667
1668         /* if update the audio clock with the pts */
1669         if (pkt->pts != AV_NOPTS_VALUE) {
1670             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1671         }
1672     }
1673 }
1674
1675 /* get the current audio output buffer size, in samples. With SDL, we
1676    cannot have a precise information */
1677 static int audio_write_get_buf_size(VideoState *is)
1678 {
1679     return is->audio_buf_size - is->audio_buf_index;
1680 }
1681
1682
1683 /* prepare a new audio buffer */
1684 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1685 {
1686     VideoState *is = opaque;
1687     int audio_size, len1;
1688     double pts;
1689
1690     audio_callback_time = av_gettime();
1691
1692     while (len > 0) {
1693         if (is->audio_buf_index >= is->audio_buf_size) {
1694            audio_size = audio_decode_frame(is, &pts);
1695            if (audio_size < 0) {
1696                 /* if error, just output silence */
1697                is->audio_buf = is->audio_buf1;
1698                is->audio_buf_size = 1024;
1699                memset(is->audio_buf, 0, is->audio_buf_size);
1700            } else {
1701                if (is->show_audio)
1702                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1703                audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1704                                               pts);
1705                is->audio_buf_size = audio_size;
1706            }
1707            is->audio_buf_index = 0;
1708         }
1709         len1 = is->audio_buf_size - is->audio_buf_index;
1710         if (len1 > len)
1711             len1 = len;
1712         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1713         len -= len1;
1714         stream += len1;
1715         is->audio_buf_index += len1;
1716     }
1717 }
1718
1719 /* open a given stream. Return 0 if OK */
1720 static int stream_component_open(VideoState *is, int stream_index)
1721 {
1722     AVFormatContext *ic = is->ic;
1723     AVCodecContext *enc;
1724     AVCodec *codec;
1725     SDL_AudioSpec wanted_spec, spec;
1726
1727     if (stream_index < 0 || stream_index >= ic->nb_streams)
1728         return -1;
1729     enc = ic->streams[stream_index]->codec;
1730
1731     /* prepare audio output */
1732     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1733         if (enc->channels > 0) {
1734             enc->request_channels = FFMIN(2, enc->channels);
1735         } else {
1736             enc->request_channels = 2;
1737         }
1738     }
1739
1740     codec = avcodec_find_decoder(enc->codec_id);
1741     enc->debug_mv = debug_mv;
1742     enc->debug = debug;
1743     enc->workaround_bugs = workaround_bugs;
1744     enc->lowres = lowres;
1745     if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1746     enc->idct_algo= idct;
1747     if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1748     enc->skip_frame= skip_frame;
1749     enc->skip_idct= skip_idct;
1750     enc->skip_loop_filter= skip_loop_filter;
1751     enc->error_recognition= error_recognition;
1752     enc->error_concealment= error_concealment;
1753
1754     set_context_opts(enc, avctx_opts[enc->codec_type], 0);
1755
1756     if (!codec ||
1757         avcodec_open(enc, codec) < 0)
1758         return -1;
1759
1760     /* prepare audio output */
1761     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1762         wanted_spec.freq = enc->sample_rate;
1763         wanted_spec.format = AUDIO_S16SYS;
1764         wanted_spec.channels = enc->channels;
1765         wanted_spec.silence = 0;
1766         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1767         wanted_spec.callback = sdl_audio_callback;
1768         wanted_spec.userdata = is;
1769         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1770             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1771             return -1;
1772         }
1773         is->audio_hw_buf_size = spec.size;
1774         is->audio_src_fmt= SAMPLE_FMT_S16;
1775     }
1776
1777     if(thread_count>1)
1778         avcodec_thread_init(enc, thread_count);
1779     enc->thread_count= thread_count;
1780     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1781     switch(enc->codec_type) {
1782     case CODEC_TYPE_AUDIO:
1783         is->audio_stream = stream_index;
1784         is->audio_st = ic->streams[stream_index];
1785         is->audio_buf_size = 0;
1786         is->audio_buf_index = 0;
1787
1788         /* init averaging filter */
1789         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1790         is->audio_diff_avg_count = 0;
1791         /* since we do not have a precise anough audio fifo fullness,
1792            we correct audio sync only if larger than this threshold */
1793         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1794
1795         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1796         packet_queue_init(&is->audioq);
1797         SDL_PauseAudio(0);
1798         break;
1799     case CODEC_TYPE_VIDEO:
1800         is->video_stream = stream_index;
1801         is->video_st = ic->streams[stream_index];
1802
1803         is->frame_last_delay = 40e-3;
1804         is->frame_timer = (double)av_gettime() / 1000000.0;
1805         is->video_current_pts_time = av_gettime();
1806
1807         packet_queue_init(&is->videoq);
1808         is->video_tid = SDL_CreateThread(video_thread, is);
1809         break;
1810     case CODEC_TYPE_SUBTITLE:
1811         is->subtitle_stream = stream_index;
1812         is->subtitle_st = ic->streams[stream_index];
1813         packet_queue_init(&is->subtitleq);
1814
1815         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1816         break;
1817     default:
1818         break;
1819     }
1820     return 0;
1821 }
1822
1823 static void stream_component_close(VideoState *is, int stream_index)
1824 {
1825     AVFormatContext *ic = is->ic;
1826     AVCodecContext *enc;
1827
1828     if (stream_index < 0 || stream_index >= ic->nb_streams)
1829         return;
1830     enc = ic->streams[stream_index]->codec;
1831
1832     switch(enc->codec_type) {
1833     case CODEC_TYPE_AUDIO:
1834         packet_queue_abort(&is->audioq);
1835
1836         SDL_CloseAudio();
1837
1838         packet_queue_end(&is->audioq);
1839         if (is->reformat_ctx)
1840             av_audio_convert_free(is->reformat_ctx);
1841         break;
1842     case CODEC_TYPE_VIDEO:
1843         packet_queue_abort(&is->videoq);
1844
1845         /* note: we also signal this mutex to make sure we deblock the
1846            video thread in all cases */
1847         SDL_LockMutex(is->pictq_mutex);
1848         SDL_CondSignal(is->pictq_cond);
1849         SDL_UnlockMutex(is->pictq_mutex);
1850
1851         SDL_WaitThread(is->video_tid, NULL);
1852
1853         packet_queue_end(&is->videoq);
1854         break;
1855     case CODEC_TYPE_SUBTITLE:
1856         packet_queue_abort(&is->subtitleq);
1857
1858         /* note: we also signal this mutex to make sure we deblock the
1859            video thread in all cases */
1860         SDL_LockMutex(is->subpq_mutex);
1861         is->subtitle_stream_changed = 1;
1862
1863         SDL_CondSignal(is->subpq_cond);
1864         SDL_UnlockMutex(is->subpq_mutex);
1865
1866         SDL_WaitThread(is->subtitle_tid, NULL);
1867
1868         packet_queue_end(&is->subtitleq);
1869         break;
1870     default:
1871         break;
1872     }
1873
1874     ic->streams[stream_index]->discard = AVDISCARD_ALL;
1875     avcodec_close(enc);
1876     switch(enc->codec_type) {
1877     case CODEC_TYPE_AUDIO:
1878         is->audio_st = NULL;
1879         is->audio_stream = -1;
1880         break;
1881     case CODEC_TYPE_VIDEO:
1882         is->video_st = NULL;
1883         is->video_stream = -1;
1884         break;
1885     case CODEC_TYPE_SUBTITLE:
1886         is->subtitle_st = NULL;
1887         is->subtitle_stream = -1;
1888         break;
1889     default:
1890         break;
1891     }
1892 }
1893
1894 static void dump_stream_info(const AVFormatContext *s)
1895 {
1896     if (s->track != 0)
1897         fprintf(stderr, "Track: %d\n", s->track);
1898     if (s->title[0] != '\0')
1899         fprintf(stderr, "Title: %s\n", s->title);
1900     if (s->author[0] != '\0')
1901         fprintf(stderr, "Author: %s\n", s->author);
1902     if (s->copyright[0] != '\0')
1903         fprintf(stderr, "Copyright: %s\n", s->copyright);
1904     if (s->comment[0] != '\0')
1905         fprintf(stderr, "Comment: %s\n", s->comment);
1906     if (s->album[0] != '\0')
1907         fprintf(stderr, "Album: %s\n", s->album);
1908     if (s->year != 0)
1909         fprintf(stderr, "Year: %d\n", s->year);
1910     if (s->genre[0] != '\0')
1911         fprintf(stderr, "Genre: %s\n", s->genre);
1912 }
1913
1914 /* since we have only one decoding thread, we can use a global
1915    variable instead of a thread local variable */
1916 static VideoState *global_video_state;
1917
1918 static int decode_interrupt_cb(void)
1919 {
1920     return (global_video_state && global_video_state->abort_request);
1921 }
1922
1923 /* this thread gets the stream from the disk or the network */
1924 static int decode_thread(void *arg)
1925 {
1926     VideoState *is = arg;
1927     AVFormatContext *ic;
1928     int err, i, ret, video_index, audio_index, subtitle_index;
1929     AVPacket pkt1, *pkt = &pkt1;
1930     AVFormatParameters params, *ap = &params;
1931
1932     video_index = -1;
1933     audio_index = -1;
1934     subtitle_index = -1;
1935     is->video_stream = -1;
1936     is->audio_stream = -1;
1937     is->subtitle_stream = -1;
1938
1939     global_video_state = is;
1940     url_set_interrupt_cb(decode_interrupt_cb);
1941
1942     memset(ap, 0, sizeof(*ap));
1943
1944     ap->width = frame_width;
1945     ap->height= frame_height;
1946     ap->time_base= (AVRational){1, 25};
1947     ap->pix_fmt = frame_pix_fmt;
1948
1949     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1950     if (err < 0) {
1951         print_error(is->filename, err);
1952         ret = -1;
1953         goto fail;
1954     }
1955     is->ic = ic;
1956
1957     if(genpts)
1958         ic->flags |= AVFMT_FLAG_GENPTS;
1959
1960     err = av_find_stream_info(ic);
1961     if (err < 0) {
1962         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1963         ret = -1;
1964         goto fail;
1965     }
1966     if(ic->pb)
1967         ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1968
1969     /* if seeking requested, we execute it */
1970     if (start_time != AV_NOPTS_VALUE) {
1971         int64_t timestamp;
1972
1973         timestamp = start_time;
1974         /* add the stream start time */
1975         if (ic->start_time != AV_NOPTS_VALUE)
1976             timestamp += ic->start_time;
1977         ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1978         if (ret < 0) {
1979             fprintf(stderr, "%s: could not seek to position %0.3f\n",
1980                     is->filename, (double)timestamp / AV_TIME_BASE);
1981         }
1982     }
1983
1984     for(i = 0; i < ic->nb_streams; i++) {
1985         AVCodecContext *enc = ic->streams[i]->codec;
1986         ic->streams[i]->discard = AVDISCARD_ALL;
1987         switch(enc->codec_type) {
1988         case CODEC_TYPE_AUDIO:
1989             if ((audio_index < 0 || wanted_audio_stream-- > 0) && !audio_disable)
1990                 audio_index = i;
1991             break;
1992         case CODEC_TYPE_VIDEO:
1993             if ((video_index < 0 || wanted_video_stream-- > 0) && !video_disable)
1994                 video_index = i;
1995             break;
1996         case CODEC_TYPE_SUBTITLE:
1997             if (wanted_subtitle_stream >= 0 && !video_disable &&
1998                     (subtitle_index < 0 || wanted_subtitle_stream-- > 0))
1999                 subtitle_index = i;
2000             break;
2001         default:
2002             break;
2003         }
2004     }
2005     if (show_status) {
2006         dump_format(ic, 0, is->filename, 0);
2007         dump_stream_info(ic);
2008     }
2009
2010     /* open the streams */
2011     if (audio_index >= 0) {
2012         stream_component_open(is, audio_index);
2013     }
2014
2015     if (video_index >= 0) {
2016         stream_component_open(is, video_index);
2017     } else {
2018         if (!display_disable)
2019             is->show_audio = 1;
2020     }
2021
2022     if (subtitle_index >= 0) {
2023         stream_component_open(is, subtitle_index);
2024     }
2025
2026     if (is->video_stream < 0 && is->audio_stream < 0) {
2027         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2028         ret = -1;
2029         goto fail;
2030     }
2031
2032     for(;;) {
2033         if (is->abort_request)
2034             break;
2035         if (is->paused != is->last_paused) {
2036             is->last_paused = is->paused;
2037             if (is->paused)
2038                 av_read_pause(ic);
2039             else
2040                 av_read_play(ic);
2041         }
2042 #if CONFIG_RTSP_DEMUXER
2043         if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2044             /* wait 10 ms to avoid trying to get another packet */
2045             /* XXX: horrible */
2046             SDL_Delay(10);
2047             continue;
2048         }
2049 #endif
2050         if (is->seek_req) {
2051             int stream_index= -1;
2052             int64_t seek_target= is->seek_pos;
2053
2054             if     (is->   video_stream >= 0) stream_index= is->   video_stream;
2055             else if(is->   audio_stream >= 0) stream_index= is->   audio_stream;
2056             else if(is->subtitle_stream >= 0) stream_index= is->subtitle_stream;
2057
2058             if(stream_index>=0){
2059                 seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, ic->streams[stream_index]->time_base);
2060             }
2061
2062             ret = av_seek_frame(is->ic, stream_index, seek_target, is->seek_flags);
2063             if (ret < 0) {
2064                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2065             }else{
2066                 if (is->audio_stream >= 0) {
2067                     packet_queue_flush(&is->audioq);
2068                     packet_queue_put(&is->audioq, &flush_pkt);
2069                 }
2070                 if (is->subtitle_stream >= 0) {
2071                     packet_queue_flush(&is->subtitleq);
2072                     packet_queue_put(&is->subtitleq, &flush_pkt);
2073                 }
2074                 if (is->video_stream >= 0) {
2075                     packet_queue_flush(&is->videoq);
2076                     packet_queue_put(&is->videoq, &flush_pkt);
2077                 }
2078             }
2079             is->seek_req = 0;
2080         }
2081
2082         /* if the queue are full, no need to read more */
2083         if (is->audioq.size > MAX_AUDIOQ_SIZE ||
2084             is->videoq.size > MAX_VIDEOQ_SIZE ||
2085             is->subtitleq.size > MAX_SUBTITLEQ_SIZE) {
2086             /* wait 10 ms */
2087             SDL_Delay(10);
2088             continue;
2089         }
2090         if(url_feof(ic->pb)) {
2091             av_init_packet(pkt);
2092             pkt->data=NULL;
2093             pkt->size=0;
2094             pkt->stream_index= is->video_stream;
2095             packet_queue_put(&is->videoq, pkt);
2096             continue;
2097         }
2098         ret = av_read_frame(ic, pkt);
2099         if (ret < 0) {
2100             if (url_ferror(ic->pb) == 0) {
2101                 SDL_Delay(100); /* wait for user event */
2102                 continue;
2103             } else
2104                 break;
2105         }
2106         if (pkt->stream_index == is->audio_stream) {
2107             packet_queue_put(&is->audioq, pkt);
2108         } else if (pkt->stream_index == is->video_stream) {
2109             packet_queue_put(&is->videoq, pkt);
2110         } else if (pkt->stream_index == is->subtitle_stream) {
2111             packet_queue_put(&is->subtitleq, pkt);
2112         } else {
2113             av_free_packet(pkt);
2114         }
2115     }
2116     /* wait until the end */
2117     while (!is->abort_request) {
2118         SDL_Delay(100);
2119     }
2120
2121     ret = 0;
2122  fail:
2123     /* disable interrupting */
2124     global_video_state = NULL;
2125
2126     /* close each stream */
2127     if (is->audio_stream >= 0)
2128         stream_component_close(is, is->audio_stream);
2129     if (is->video_stream >= 0)
2130         stream_component_close(is, is->video_stream);
2131     if (is->subtitle_stream >= 0)
2132         stream_component_close(is, is->subtitle_stream);
2133     if (is->ic) {
2134         av_close_input_file(is->ic);
2135         is->ic = NULL; /* safety */
2136     }
2137     url_set_interrupt_cb(NULL);
2138
2139     if (ret != 0) {
2140         SDL_Event event;
2141
2142         event.type = FF_QUIT_EVENT;
2143         event.user.data1 = is;
2144         SDL_PushEvent(&event);
2145     }
2146     return 0;
2147 }
2148
2149 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2150 {
2151     VideoState *is;
2152
2153     is = av_mallocz(sizeof(VideoState));
2154     if (!is)
2155         return NULL;
2156     av_strlcpy(is->filename, filename, sizeof(is->filename));
2157     is->iformat = iformat;
2158     is->ytop = 0;
2159     is->xleft = 0;
2160
2161     /* start video display */
2162     is->pictq_mutex = SDL_CreateMutex();
2163     is->pictq_cond = SDL_CreateCond();
2164
2165     is->subpq_mutex = SDL_CreateMutex();
2166     is->subpq_cond = SDL_CreateCond();
2167
2168     /* add the refresh timer to draw the picture */
2169     schedule_refresh(is, 40);
2170
2171     is->av_sync_type = av_sync_type;
2172     is->parse_tid = SDL_CreateThread(decode_thread, is);
2173     if (!is->parse_tid) {
2174         av_free(is);
2175         return NULL;
2176     }
2177     return is;
2178 }
2179
2180 static void stream_close(VideoState *is)
2181 {
2182     VideoPicture *vp;
2183     int i;
2184     /* XXX: use a special url_shutdown call to abort parse cleanly */
2185     is->abort_request = 1;
2186     SDL_WaitThread(is->parse_tid, NULL);
2187
2188     /* free all pictures */
2189     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2190         vp = &is->pictq[i];
2191         if (vp->bmp) {
2192             SDL_FreeYUVOverlay(vp->bmp);
2193             vp->bmp = NULL;
2194         }
2195     }
2196     SDL_DestroyMutex(is->pictq_mutex);
2197     SDL_DestroyCond(is->pictq_cond);
2198     SDL_DestroyMutex(is->subpq_mutex);
2199     SDL_DestroyCond(is->subpq_cond);
2200 }
2201
2202 static void stream_cycle_channel(VideoState *is, int codec_type)
2203 {
2204     AVFormatContext *ic = is->ic;
2205     int start_index, stream_index;
2206     AVStream *st;
2207
2208     if (codec_type == CODEC_TYPE_VIDEO)
2209         start_index = is->video_stream;
2210     else if (codec_type == CODEC_TYPE_AUDIO)
2211         start_index = is->audio_stream;
2212     else
2213         start_index = is->subtitle_stream;
2214     if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2215         return;
2216     stream_index = start_index;
2217     for(;;) {
2218         if (++stream_index >= is->ic->nb_streams)
2219         {
2220             if (codec_type == CODEC_TYPE_SUBTITLE)
2221             {
2222                 stream_index = -1;
2223                 goto the_end;
2224             } else
2225                 stream_index = 0;
2226         }
2227         if (stream_index == start_index)
2228             return;
2229         st = ic->streams[stream_index];
2230         if (st->codec->codec_type == codec_type) {
2231             /* check that parameters are OK */
2232             switch(codec_type) {
2233             case CODEC_TYPE_AUDIO:
2234                 if (st->codec->sample_rate != 0 &&
2235                     st->codec->channels != 0)
2236                     goto the_end;
2237                 break;
2238             case CODEC_TYPE_VIDEO:
2239             case CODEC_TYPE_SUBTITLE:
2240                 goto the_end;
2241             default:
2242                 break;
2243             }
2244         }
2245     }
2246  the_end:
2247     stream_component_close(is, start_index);
2248     stream_component_open(is, stream_index);
2249 }
2250
2251
2252 static void toggle_full_screen(void)
2253 {
2254     is_full_screen = !is_full_screen;
2255     if (!fs_screen_width) {
2256         /* use default SDL method */
2257 //        SDL_WM_ToggleFullScreen(screen);
2258     }
2259     video_open(cur_stream);
2260 }
2261
2262 static void toggle_pause(void)
2263 {
2264     if (cur_stream)
2265         stream_pause(cur_stream);
2266     step = 0;
2267 }
2268
2269 static void step_to_next_frame(void)
2270 {
2271     if (cur_stream) {
2272         /* if the stream is paused unpause it, then step */
2273         if (cur_stream->paused)
2274             stream_pause(cur_stream);
2275     }
2276     step = 1;
2277 }
2278
2279 static void do_exit(void)
2280 {
2281     if (cur_stream) {
2282         stream_close(cur_stream);
2283         cur_stream = NULL;
2284     }
2285     if (show_status)
2286         printf("\n");
2287     SDL_Quit();
2288     exit(0);
2289 }
2290
2291 static void toggle_audio_display(void)
2292 {
2293     if (cur_stream) {
2294         cur_stream->show_audio = !cur_stream->show_audio;
2295     }
2296 }
2297
2298 /* handle an event sent by the GUI */
2299 static void event_loop(void)
2300 {
2301     SDL_Event event;
2302     double incr, pos, frac;
2303
2304     for(;;) {
2305         SDL_WaitEvent(&event);
2306         switch(event.type) {
2307         case SDL_KEYDOWN:
2308             switch(event.key.keysym.sym) {
2309             case SDLK_ESCAPE:
2310             case SDLK_q:
2311                 do_exit();
2312                 break;
2313             case SDLK_f:
2314                 toggle_full_screen();
2315                 break;
2316             case SDLK_p:
2317             case SDLK_SPACE:
2318                 toggle_pause();
2319                 break;
2320             case SDLK_s: //S: Step to next frame
2321                 step_to_next_frame();
2322                 break;
2323             case SDLK_a:
2324                 if (cur_stream)
2325                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2326                 break;
2327             case SDLK_v:
2328                 if (cur_stream)
2329                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2330                 break;
2331             case SDLK_t:
2332                 if (cur_stream)
2333                     stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2334                 break;
2335             case SDLK_w:
2336                 toggle_audio_display();
2337                 break;
2338             case SDLK_LEFT:
2339                 incr = -10.0;
2340                 goto do_seek;
2341             case SDLK_RIGHT:
2342                 incr = 10.0;
2343                 goto do_seek;
2344             case SDLK_UP:
2345                 incr = 60.0;
2346                 goto do_seek;
2347             case SDLK_DOWN:
2348                 incr = -60.0;
2349             do_seek:
2350                 if (cur_stream) {
2351                     if (seek_by_bytes) {
2352                         pos = url_ftell(cur_stream->ic->pb);
2353                         if (cur_stream->ic->bit_rate)
2354                             incr *= cur_stream->ic->bit_rate / 60.0;
2355                         else
2356                             incr *= 180000.0;
2357                         pos += incr;
2358                         stream_seek(cur_stream, pos, incr);
2359                     } else {
2360                         pos = get_master_clock(cur_stream);
2361                         pos += incr;
2362                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
2363                     }
2364                 }
2365                 break;
2366             default:
2367                 break;
2368             }
2369             break;
2370         case SDL_MOUSEBUTTONDOWN:
2371             if (cur_stream) {
2372                 int ns, hh, mm, ss;
2373                 int tns, thh, tmm, tss;
2374                 tns = cur_stream->ic->duration/1000000LL;
2375                 thh = tns/3600;
2376                 tmm = (tns%3600)/60;
2377                 tss = (tns%60);
2378                 frac = (double)event.button.x/(double)cur_stream->width;
2379                 ns = frac*tns;
2380                 hh = ns/3600;
2381                 mm = (ns%3600)/60;
2382                 ss = (ns%60);
2383                 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2384                         hh, mm, ss, thh, tmm, tss);
2385                 stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
2386             }
2387             break;
2388         case SDL_VIDEORESIZE:
2389             if (cur_stream) {
2390                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2391                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2392                 screen_width = cur_stream->width = event.resize.w;
2393                 screen_height= cur_stream->height= event.resize.h;
2394             }
2395             break;
2396         case SDL_QUIT:
2397         case FF_QUIT_EVENT:
2398             do_exit();
2399             break;
2400         case FF_ALLOC_EVENT:
2401             video_open(event.user.data1);
2402             alloc_picture(event.user.data1);
2403             break;
2404         case FF_REFRESH_EVENT:
2405             video_refresh_timer(event.user.data1);
2406             break;
2407         default:
2408             break;
2409         }
2410     }
2411 }
2412
2413 static void opt_frame_size(const char *arg)
2414 {
2415     if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2416         fprintf(stderr, "Incorrect frame size\n");
2417         exit(1);
2418     }
2419     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2420         fprintf(stderr, "Frame size must be a multiple of 2\n");
2421         exit(1);
2422     }
2423 }
2424
2425 static int opt_width(const char *opt, const char *arg)
2426 {
2427     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2428     return 0;
2429 }
2430
2431 static int opt_height(const char *opt, const char *arg)
2432 {
2433     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2434     return 0;
2435 }
2436
2437 static void opt_format(const char *arg)
2438 {
2439     file_iformat = av_find_input_format(arg);
2440     if (!file_iformat) {
2441         fprintf(stderr, "Unknown input format: %s\n", arg);
2442         exit(1);
2443     }
2444 }
2445
2446 static void opt_frame_pix_fmt(const char *arg)
2447 {
2448     frame_pix_fmt = avcodec_get_pix_fmt(arg);
2449 }
2450
2451 static int opt_sync(const char *opt, const char *arg)
2452 {
2453     if (!strcmp(arg, "audio"))
2454         av_sync_type = AV_SYNC_AUDIO_MASTER;
2455     else if (!strcmp(arg, "video"))
2456         av_sync_type = AV_SYNC_VIDEO_MASTER;
2457     else if (!strcmp(arg, "ext"))
2458         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2459     else {
2460         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2461         exit(1);
2462     }
2463     return 0;
2464 }
2465
2466 static int opt_seek(const char *opt, const char *arg)
2467 {
2468     start_time = parse_time_or_die(opt, arg, 1);
2469     return 0;
2470 }
2471
2472 static int opt_debug(const char *opt, const char *arg)
2473 {
2474     av_log_set_level(99);
2475     debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2476     return 0;
2477 }
2478
2479 static int opt_vismv(const char *opt, const char *arg)
2480 {
2481     debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2482     return 0;
2483 }
2484
2485 static int opt_thread_count(const char *opt, const char *arg)
2486 {
2487     thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2488 #if !HAVE_THREADS
2489     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2490 #endif
2491     return 0;
2492 }
2493
2494 static const OptionDef options[] = {
2495     { "h", OPT_EXIT, {(void*)show_help}, "show help" },
2496     { "version", OPT_EXIT, {(void*)show_version}, "show version" },
2497     { "L", OPT_EXIT, {(void*)show_license}, "show license" },
2498     { "formats", OPT_EXIT, {(void*)show_formats}, "show available formats, codecs, protocols, ..." },
2499     { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2500     { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2501     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2502     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2503     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2504     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2505     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "", "" },
2506     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "", "" },
2507     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "", "" },
2508     { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2509     { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2510     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2511     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2512     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2513     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2514     { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2515     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2516     { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2517     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2518     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2519     { "drp", OPT_BOOL |OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts", ""},
2520     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2521     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2522     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2523     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2524     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2525     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2526     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2527     { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2528     { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2529     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2530     { NULL, },
2531 };
2532
2533 static void show_help(void)
2534 {
2535     printf("usage: ffplay [options] input_file\n"
2536            "Simple media player\n");
2537     printf("\n");
2538     show_help_options(options, "Main options:\n",
2539                       OPT_EXPERT, 0);
2540     show_help_options(options, "\nAdvanced options:\n",
2541                       OPT_EXPERT, OPT_EXPERT);
2542     printf("\nWhile playing:\n"
2543            "q, ESC              quit\n"
2544            "f                   toggle full screen\n"
2545            "p, SPC              pause\n"
2546            "a                   cycle audio channel\n"
2547            "v                   cycle video channel\n"
2548            "t                   cycle subtitle channel\n"
2549            "w                   show audio waves\n"
2550            "left/right          seek backward/forward 10 seconds\n"
2551            "down/up             seek backward/forward 1 minute\n"
2552            "mouse click         seek to percentage in file corresponding to fraction of width\n"
2553            );
2554 }
2555
2556 static void opt_input_file(const char *filename)
2557 {
2558     if (!strcmp(filename, "-"))
2559         filename = "pipe:";
2560     input_filename = filename;
2561 }
2562
2563 /* Called from the main */
2564 int main(int argc, char **argv)
2565 {
2566     int flags, i;
2567
2568     /* register all codecs, demux and protocols */
2569     avcodec_register_all();
2570     avdevice_register_all();
2571     av_register_all();
2572
2573     for(i=0; i<CODEC_TYPE_NB; i++){
2574         avctx_opts[i]= avcodec_alloc_context2(i);
2575     }
2576     avformat_opts = avformat_alloc_context();
2577     sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2578
2579     show_banner();
2580
2581     parse_options(argc, argv, options, opt_input_file);
2582
2583     if (!input_filename) {
2584         fprintf(stderr, "An input file must be specified\n");
2585         exit(1);
2586     }
2587
2588     if (display_disable) {
2589         video_disable = 1;
2590     }
2591     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2592 #if !defined(__MINGW32__) && !defined(__APPLE__)
2593     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2594 #endif
2595     if (SDL_Init (flags)) {
2596         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2597         exit(1);
2598     }
2599
2600     if (!display_disable) {
2601 #if HAVE_SDL_VIDEO_SIZE
2602         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2603         fs_screen_width = vi->current_w;
2604         fs_screen_height = vi->current_h;
2605 #endif
2606     }
2607
2608     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2609     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2610     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2611     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2612
2613     av_init_packet(&flush_pkt);
2614     flush_pkt.data= "FLUSH";
2615
2616     cur_stream = stream_open(input_filename, file_iformat);
2617
2618     event_loop();
2619
2620     /* never returns */
2621
2622     return 0;
2623 }