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