Display a more descriptive log message when probe buffer limit is
[ffmpeg.git] / ffplay.c
1 /*
2  * FFplay : Simple Media Player based on the FFmpeg libraries
3  * Copyright (c) 2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "config.h"
23 #include <inttypes.h>
24 #include <math.h>
25 #include <limits.h>
26 #include "libavutil/avstring.h"
27 #include "libavutil/pixdesc.h"
28 #include "libavformat/avformat.h"
29 #include "libavdevice/avdevice.h"
30 #include "libswscale/swscale.h"
31 #include "libavcodec/audioconvert.h"
32 #include "libavcodec/colorspace.h"
33 #include "libavcodec/opt.h"
34 #include "libavcodec/avfft.h"
35
36 #if CONFIG_AVFILTER
37 # include "libavfilter/avfilter.h"
38 # include "libavfilter/avfiltergraph.h"
39 # include "libavfilter/graphparser.h"
40 #endif
41
42 #include "cmdutils.h"
43
44 #include <SDL.h>
45 #include <SDL_thread.h>
46
47 #ifdef __MINGW32__
48 #undef main /* We don't want SDL to override our main() */
49 #endif
50
51 #include <unistd.h>
52 #include <assert.h>
53
54 const char program_name[] = "FFplay";
55 const int program_birth_year = 2003;
56
57 //#define DEBUG_SYNC
58
59 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
60 #define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
61 #define MIN_FRAMES 5
62
63 /* SDL audio buffer size, in samples. Should be small to have precise
64    A/V sync as SDL does not have hardware buffer fullness info. */
65 #define SDL_AUDIO_BUFFER_SIZE 1024
66
67 /* no AV sync correction is done if below the AV sync threshold */
68 #define AV_SYNC_THRESHOLD 0.01
69 /* no AV correction is done if too big error */
70 #define AV_NOSYNC_THRESHOLD 10.0
71
72 #define FRAME_SKIP_FACTOR 0.05
73
74 /* maximum audio speed change to get correct sync */
75 #define SAMPLE_CORRECTION_PERCENT_MAX 10
76
77 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
78 #define AUDIO_DIFF_AVG_NB   20
79
80 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
81 #define SAMPLE_ARRAY_SIZE (2*65536)
82
83 static int sws_flags = SWS_BICUBIC;
84
85 typedef struct PacketQueue {
86     AVPacketList *first_pkt, *last_pkt;
87     int nb_packets;
88     int size;
89     int abort_request;
90     SDL_mutex *mutex;
91     SDL_cond *cond;
92 } PacketQueue;
93
94 #define VIDEO_PICTURE_QUEUE_SIZE 2
95 #define SUBPICTURE_QUEUE_SIZE 4
96
97 typedef struct VideoPicture {
98     double pts;                                  ///<presentation time stamp for this picture
99     double target_clock;                         ///<av_gettime() time at which this should be displayed ideally
100     int64_t pos;                                 ///<byte position in file
101     SDL_Overlay *bmp;
102     int width, height; /* source height & width */
103     int allocated;
104     enum PixelFormat pix_fmt;
105
106 #if CONFIG_AVFILTER
107     AVFilterPicRef *picref;
108 #endif
109 } VideoPicture;
110
111 typedef struct SubPicture {
112     double pts; /* presentation time stamp for this picture */
113     AVSubtitle sub;
114 } SubPicture;
115
116 enum {
117     AV_SYNC_AUDIO_MASTER, /* default choice */
118     AV_SYNC_VIDEO_MASTER,
119     AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
120 };
121
122 typedef struct VideoState {
123     SDL_Thread *parse_tid;
124     SDL_Thread *video_tid;
125     SDL_Thread *refresh_tid;
126     AVInputFormat *iformat;
127     int no_background;
128     int abort_request;
129     int paused;
130     int last_paused;
131     int seek_req;
132     int seek_flags;
133     int64_t seek_pos;
134     int64_t seek_rel;
135     int read_pause_return;
136     AVFormatContext *ic;
137     int dtg_active_format;
138
139     int audio_stream;
140
141     int av_sync_type;
142     double external_clock; /* external clock base */
143     int64_t external_clock_time;
144
145     double audio_clock;
146     double audio_diff_cum; /* used for AV difference average computation */
147     double audio_diff_avg_coef;
148     double audio_diff_threshold;
149     int audio_diff_avg_count;
150     AVStream *audio_st;
151     PacketQueue audioq;
152     int audio_hw_buf_size;
153     /* samples output by the codec. we reserve more space for avsync
154        compensation */
155     DECLARE_ALIGNED(16,uint8_t,audio_buf1)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
156     DECLARE_ALIGNED(16,uint8_t,audio_buf2)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
157     uint8_t *audio_buf;
158     unsigned int audio_buf_size; /* in bytes */
159     int audio_buf_index; /* in bytes */
160     AVPacket audio_pkt_temp;
161     AVPacket audio_pkt;
162     enum SampleFormat audio_src_fmt;
163     AVAudioConvert *reformat_ctx;
164
165     int show_audio; /* if true, display audio samples */
166     int16_t sample_array[SAMPLE_ARRAY_SIZE];
167     int sample_array_index;
168     int last_i_start;
169     RDFTContext *rdft;
170     int rdft_bits;
171     int xpos;
172
173     SDL_Thread *subtitle_tid;
174     int subtitle_stream;
175     int subtitle_stream_changed;
176     AVStream *subtitle_st;
177     PacketQueue subtitleq;
178     SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
179     int subpq_size, subpq_rindex, subpq_windex;
180     SDL_mutex *subpq_mutex;
181     SDL_cond *subpq_cond;
182
183     double frame_timer;
184     double frame_last_pts;
185     double frame_last_delay;
186     double video_clock;                          ///<pts of last decoded frame / predicted pts of next decoded frame
187     int video_stream;
188     AVStream *video_st;
189     PacketQueue videoq;
190     double video_current_pts;                    ///<current displayed pts (different from video_clock if frame fifos are used)
191     double video_current_pts_drift;              ///<video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
192     int64_t video_current_pos;                   ///<current displayed file pos
193     VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
194     int pictq_size, pictq_rindex, pictq_windex;
195     SDL_mutex *pictq_mutex;
196     SDL_cond *pictq_cond;
197 #if !CONFIG_AVFILTER
198     struct SwsContext *img_convert_ctx;
199 #endif
200
201     //    QETimer *video_timer;
202     char filename[1024];
203     int width, height, xleft, ytop;
204
205     int64_t faulty_pts;
206     int64_t faulty_dts;
207     int64_t last_dts_for_fault_detection;
208     int64_t last_pts_for_fault_detection;
209
210 #if CONFIG_AVFILTER
211     AVFilterContext *out_video_filter;          ///<the last filter in the video chain
212 #endif
213
214     float skip_frames;
215     float skip_frames_index;
216     int refresh;
217 } VideoState;
218
219 static void show_help(void);
220 static int audio_write_get_buf_size(VideoState *is);
221
222 /* options specified by the user */
223 static AVInputFormat *file_iformat;
224 static const char *input_filename;
225 static const char *window_title;
226 static int fs_screen_width;
227 static int fs_screen_height;
228 static int screen_width = 0;
229 static int screen_height = 0;
230 static int frame_width = 0;
231 static int frame_height = 0;
232 static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
233 static int audio_disable;
234 static int video_disable;
235 static int wanted_stream[AVMEDIA_TYPE_NB]={
236     [AVMEDIA_TYPE_AUDIO]=-1,
237     [AVMEDIA_TYPE_VIDEO]=-1,
238     [AVMEDIA_TYPE_SUBTITLE]=-1,
239 };
240 static int seek_by_bytes=-1;
241 static int display_disable;
242 static int show_status = 1;
243 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
244 static int64_t start_time = AV_NOPTS_VALUE;
245 static int64_t duration = AV_NOPTS_VALUE;
246 static int debug = 0;
247 static int debug_mv = 0;
248 static int step = 0;
249 static int thread_count = 1;
250 static int workaround_bugs = 1;
251 static int fast = 0;
252 static int genpts = 0;
253 static int lowres = 0;
254 static int idct = FF_IDCT_AUTO;
255 static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
256 static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
257 static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
258 static int error_recognition = FF_ER_CAREFUL;
259 static int error_concealment = 3;
260 static int decoder_reorder_pts= -1;
261 static int autoexit;
262 static int loop=1;
263 static int framedrop=1;
264
265 static int rdftspeed=20;
266 #if CONFIG_AVFILTER
267 static char *vfilters = NULL;
268 #endif
269
270 /* current context */
271 static int is_full_screen;
272 static VideoState *cur_stream;
273 static int64_t audio_callback_time;
274
275 static AVPacket flush_pkt;
276
277 #define FF_ALLOC_EVENT   (SDL_USEREVENT)
278 #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
279 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
280
281 static SDL_Surface *screen;
282
283 static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
284
285 /* packet queue handling */
286 static void packet_queue_init(PacketQueue *q)
287 {
288     memset(q, 0, sizeof(PacketQueue));
289     q->mutex = SDL_CreateMutex();
290     q->cond = SDL_CreateCond();
291     packet_queue_put(q, &flush_pkt);
292 }
293
294 static void packet_queue_flush(PacketQueue *q)
295 {
296     AVPacketList *pkt, *pkt1;
297
298     SDL_LockMutex(q->mutex);
299     for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
300         pkt1 = pkt->next;
301         av_free_packet(&pkt->pkt);
302         av_freep(&pkt);
303     }
304     q->last_pkt = NULL;
305     q->first_pkt = NULL;
306     q->nb_packets = 0;
307     q->size = 0;
308     SDL_UnlockMutex(q->mutex);
309 }
310
311 static void packet_queue_end(PacketQueue *q)
312 {
313     packet_queue_flush(q);
314     SDL_DestroyMutex(q->mutex);
315     SDL_DestroyCond(q->cond);
316 }
317
318 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
319 {
320     AVPacketList *pkt1;
321
322     /* duplicate the packet */
323     if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
324         return -1;
325
326     pkt1 = av_malloc(sizeof(AVPacketList));
327     if (!pkt1)
328         return -1;
329     pkt1->pkt = *pkt;
330     pkt1->next = NULL;
331
332
333     SDL_LockMutex(q->mutex);
334
335     if (!q->last_pkt)
336
337         q->first_pkt = pkt1;
338     else
339         q->last_pkt->next = pkt1;
340     q->last_pkt = pkt1;
341     q->nb_packets++;
342     q->size += pkt1->pkt.size + sizeof(*pkt1);
343     /* XXX: should duplicate packet data in DV case */
344     SDL_CondSignal(q->cond);
345
346     SDL_UnlockMutex(q->mutex);
347     return 0;
348 }
349
350 static void packet_queue_abort(PacketQueue *q)
351 {
352     SDL_LockMutex(q->mutex);
353
354     q->abort_request = 1;
355
356     SDL_CondSignal(q->cond);
357
358     SDL_UnlockMutex(q->mutex);
359 }
360
361 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
362 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
363 {
364     AVPacketList *pkt1;
365     int ret;
366
367     SDL_LockMutex(q->mutex);
368
369     for(;;) {
370         if (q->abort_request) {
371             ret = -1;
372             break;
373         }
374
375         pkt1 = q->first_pkt;
376         if (pkt1) {
377             q->first_pkt = pkt1->next;
378             if (!q->first_pkt)
379                 q->last_pkt = NULL;
380             q->nb_packets--;
381             q->size -= pkt1->pkt.size + sizeof(*pkt1);
382             *pkt = pkt1->pkt;
383             av_free(pkt1);
384             ret = 1;
385             break;
386         } else if (!block) {
387             ret = 0;
388             break;
389         } else {
390             SDL_CondWait(q->cond, q->mutex);
391         }
392     }
393     SDL_UnlockMutex(q->mutex);
394     return ret;
395 }
396
397 static inline void fill_rectangle(SDL_Surface *screen,
398                                   int x, int y, int w, int h, int color)
399 {
400     SDL_Rect rect;
401     rect.x = x;
402     rect.y = y;
403     rect.w = w;
404     rect.h = h;
405     SDL_FillRect(screen, &rect, color);
406 }
407
408 #if 0
409 /* draw only the border of a rectangle */
410 void fill_border(VideoState *s, int x, int y, int w, int h, int color)
411 {
412     int w1, w2, h1, h2;
413
414     /* fill the background */
415     w1 = x;
416     if (w1 < 0)
417         w1 = 0;
418     w2 = s->width - (x + w);
419     if (w2 < 0)
420         w2 = 0;
421     h1 = y;
422     if (h1 < 0)
423         h1 = 0;
424     h2 = s->height - (y + h);
425     if (h2 < 0)
426         h2 = 0;
427     fill_rectangle(screen,
428                    s->xleft, s->ytop,
429                    w1, s->height,
430                    color);
431     fill_rectangle(screen,
432                    s->xleft + s->width - w2, s->ytop,
433                    w2, s->height,
434                    color);
435     fill_rectangle(screen,
436                    s->xleft + w1, s->ytop,
437                    s->width - w1 - w2, h1,
438                    color);
439     fill_rectangle(screen,
440                    s->xleft + w1, s->ytop + s->height - h2,
441                    s->width - w1 - w2, h2,
442                    color);
443 }
444 #endif
445
446 #define ALPHA_BLEND(a, oldp, newp, s)\
447 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
448
449 #define RGBA_IN(r, g, b, a, s)\
450 {\
451     unsigned int v = ((const uint32_t *)(s))[0];\
452     a = (v >> 24) & 0xff;\
453     r = (v >> 16) & 0xff;\
454     g = (v >> 8) & 0xff;\
455     b = v & 0xff;\
456 }
457
458 #define YUVA_IN(y, u, v, a, s, pal)\
459 {\
460     unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
461     a = (val >> 24) & 0xff;\
462     y = (val >> 16) & 0xff;\
463     u = (val >> 8) & 0xff;\
464     v = val & 0xff;\
465 }
466
467 #define YUVA_OUT(d, y, u, v, a)\
468 {\
469     ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
470 }
471
472
473 #define BPP 1
474
475 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
476 {
477     int wrap, wrap3, width2, skip2;
478     int y, u, v, a, u1, v1, a1, w, h;
479     uint8_t *lum, *cb, *cr;
480     const uint8_t *p;
481     const uint32_t *pal;
482     int dstx, dsty, dstw, dsth;
483
484     dstw = av_clip(rect->w, 0, imgw);
485     dsth = av_clip(rect->h, 0, imgh);
486     dstx = av_clip(rect->x, 0, imgw - dstw);
487     dsty = av_clip(rect->y, 0, imgh - dsth);
488     lum = dst->data[0] + dsty * dst->linesize[0];
489     cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
490     cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
491
492     width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
493     skip2 = dstx >> 1;
494     wrap = dst->linesize[0];
495     wrap3 = rect->pict.linesize[0];
496     p = rect->pict.data[0];
497     pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
498
499     if (dsty & 1) {
500         lum += dstx;
501         cb += skip2;
502         cr += skip2;
503
504         if (dstx & 1) {
505             YUVA_IN(y, u, v, a, p, pal);
506             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
507             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
508             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
509             cb++;
510             cr++;
511             lum++;
512             p += BPP;
513         }
514         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
515             YUVA_IN(y, u, v, a, p, pal);
516             u1 = u;
517             v1 = v;
518             a1 = a;
519             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
520
521             YUVA_IN(y, u, v, a, p + BPP, pal);
522             u1 += u;
523             v1 += v;
524             a1 += a;
525             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
526             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
527             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
528             cb++;
529             cr++;
530             p += 2 * BPP;
531             lum += 2;
532         }
533         if (w) {
534             YUVA_IN(y, u, v, a, p, pal);
535             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
536             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
537             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
538             p++;
539             lum++;
540         }
541         p += wrap3 - dstw * BPP;
542         lum += wrap - dstw - dstx;
543         cb += dst->linesize[1] - width2 - skip2;
544         cr += dst->linesize[2] - width2 - skip2;
545     }
546     for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
547         lum += dstx;
548         cb += skip2;
549         cr += skip2;
550
551         if (dstx & 1) {
552             YUVA_IN(y, u, v, a, p, pal);
553             u1 = u;
554             v1 = v;
555             a1 = a;
556             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
557             p += wrap3;
558             lum += wrap;
559             YUVA_IN(y, u, v, a, p, pal);
560             u1 += u;
561             v1 += v;
562             a1 += a;
563             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
564             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
565             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
566             cb++;
567             cr++;
568             p += -wrap3 + BPP;
569             lum += -wrap + 1;
570         }
571         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
572             YUVA_IN(y, u, v, a, p, pal);
573             u1 = u;
574             v1 = v;
575             a1 = a;
576             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
577
578             YUVA_IN(y, u, v, a, p + BPP, pal);
579             u1 += u;
580             v1 += v;
581             a1 += a;
582             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
583             p += wrap3;
584             lum += wrap;
585
586             YUVA_IN(y, u, v, a, p, pal);
587             u1 += u;
588             v1 += v;
589             a1 += a;
590             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
591
592             YUVA_IN(y, u, v, a, p + BPP, pal);
593             u1 += u;
594             v1 += v;
595             a1 += a;
596             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
597
598             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
599             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
600
601             cb++;
602             cr++;
603             p += -wrap3 + 2 * BPP;
604             lum += -wrap + 2;
605         }
606         if (w) {
607             YUVA_IN(y, u, v, a, p, pal);
608             u1 = u;
609             v1 = v;
610             a1 = a;
611             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
612             p += wrap3;
613             lum += wrap;
614             YUVA_IN(y, u, v, a, p, pal);
615             u1 += u;
616             v1 += v;
617             a1 += a;
618             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
619             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
620             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
621             cb++;
622             cr++;
623             p += -wrap3 + BPP;
624             lum += -wrap + 1;
625         }
626         p += wrap3 + (wrap3 - dstw * BPP);
627         lum += wrap + (wrap - dstw - dstx);
628         cb += dst->linesize[1] - width2 - skip2;
629         cr += dst->linesize[2] - width2 - skip2;
630     }
631     /* handle odd height */
632     if (h) {
633         lum += dstx;
634         cb += skip2;
635         cr += skip2;
636
637         if (dstx & 1) {
638             YUVA_IN(y, u, v, a, p, pal);
639             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
640             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
641             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
642             cb++;
643             cr++;
644             lum++;
645             p += BPP;
646         }
647         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
648             YUVA_IN(y, u, v, a, p, pal);
649             u1 = u;
650             v1 = v;
651             a1 = a;
652             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
653
654             YUVA_IN(y, u, v, a, p + BPP, pal);
655             u1 += u;
656             v1 += v;
657             a1 += a;
658             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
659             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
660             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
661             cb++;
662             cr++;
663             p += 2 * BPP;
664             lum += 2;
665         }
666         if (w) {
667             YUVA_IN(y, u, v, a, p, pal);
668             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
669             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
670             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
671         }
672     }
673 }
674
675 static void free_subpicture(SubPicture *sp)
676 {
677     int i;
678
679     for (i = 0; i < sp->sub.num_rects; i++)
680     {
681         av_freep(&sp->sub.rects[i]->pict.data[0]);
682         av_freep(&sp->sub.rects[i]->pict.data[1]);
683         av_freep(&sp->sub.rects[i]);
684     }
685
686     av_free(sp->sub.rects);
687
688     memset(&sp->sub, 0, sizeof(AVSubtitle));
689 }
690
691 static void video_image_display(VideoState *is)
692 {
693     VideoPicture *vp;
694     SubPicture *sp;
695     AVPicture pict;
696     float aspect_ratio;
697     int width, height, x, y;
698     SDL_Rect rect;
699     int i;
700
701     vp = &is->pictq[is->pictq_rindex];
702     if (vp->bmp) {
703 #if CONFIG_AVFILTER
704          if (vp->picref->pixel_aspect.num == 0)
705              aspect_ratio = 0;
706          else
707              aspect_ratio = av_q2d(vp->picref->pixel_aspect);
708 #else
709
710         /* XXX: use variable in the frame */
711         if (is->video_st->sample_aspect_ratio.num)
712             aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
713         else if (is->video_st->codec->sample_aspect_ratio.num)
714             aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
715         else
716             aspect_ratio = 0;
717 #endif
718         if (aspect_ratio <= 0.0)
719             aspect_ratio = 1.0;
720         aspect_ratio *= (float)vp->width / (float)vp->height;
721         /* if an active format is indicated, then it overrides the
722            mpeg format */
723 #if 0
724         if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
725             is->dtg_active_format = is->video_st->codec->dtg_active_format;
726             printf("dtg_active_format=%d\n", is->dtg_active_format);
727         }
728 #endif
729 #if 0
730         switch(is->video_st->codec->dtg_active_format) {
731         case FF_DTG_AFD_SAME:
732         default:
733             /* nothing to do */
734             break;
735         case FF_DTG_AFD_4_3:
736             aspect_ratio = 4.0 / 3.0;
737             break;
738         case FF_DTG_AFD_16_9:
739             aspect_ratio = 16.0 / 9.0;
740             break;
741         case FF_DTG_AFD_14_9:
742             aspect_ratio = 14.0 / 9.0;
743             break;
744         case FF_DTG_AFD_4_3_SP_14_9:
745             aspect_ratio = 14.0 / 9.0;
746             break;
747         case FF_DTG_AFD_16_9_SP_14_9:
748             aspect_ratio = 14.0 / 9.0;
749             break;
750         case FF_DTG_AFD_SP_4_3:
751             aspect_ratio = 4.0 / 3.0;
752             break;
753         }
754 #endif
755
756         if (is->subtitle_st)
757         {
758             if (is->subpq_size > 0)
759             {
760                 sp = &is->subpq[is->subpq_rindex];
761
762                 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
763                 {
764                     SDL_LockYUVOverlay (vp->bmp);
765
766                     pict.data[0] = vp->bmp->pixels[0];
767                     pict.data[1] = vp->bmp->pixels[2];
768                     pict.data[2] = vp->bmp->pixels[1];
769
770                     pict.linesize[0] = vp->bmp->pitches[0];
771                     pict.linesize[1] = vp->bmp->pitches[2];
772                     pict.linesize[2] = vp->bmp->pitches[1];
773
774                     for (i = 0; i < sp->sub.num_rects; i++)
775                         blend_subrect(&pict, sp->sub.rects[i],
776                                       vp->bmp->w, vp->bmp->h);
777
778                     SDL_UnlockYUVOverlay (vp->bmp);
779                 }
780             }
781         }
782
783
784         /* XXX: we suppose the screen has a 1.0 pixel ratio */
785         height = is->height;
786         width = ((int)rint(height * aspect_ratio)) & ~1;
787         if (width > is->width) {
788             width = is->width;
789             height = ((int)rint(width / aspect_ratio)) & ~1;
790         }
791         x = (is->width - width) / 2;
792         y = (is->height - height) / 2;
793         if (!is->no_background) {
794             /* fill the background */
795             //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
796         } else {
797             is->no_background = 0;
798         }
799         rect.x = is->xleft + x;
800         rect.y = is->ytop  + y;
801         rect.w = width;
802         rect.h = height;
803         SDL_DisplayYUVOverlay(vp->bmp, &rect);
804     } else {
805 #if 0
806         fill_rectangle(screen,
807                        is->xleft, is->ytop, is->width, is->height,
808                        QERGB(0x00, 0x00, 0x00));
809 #endif
810     }
811 }
812
813 static inline int compute_mod(int a, int b)
814 {
815     a = a % b;
816     if (a >= 0)
817         return a;
818     else
819         return a + b;
820 }
821
822 static void video_audio_display(VideoState *s)
823 {
824     int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
825     int ch, channels, h, h2, bgcolor, fgcolor;
826     int16_t time_diff;
827     int rdft_bits, nb_freq;
828
829     for(rdft_bits=1; (1<<rdft_bits)<2*s->height; rdft_bits++)
830         ;
831     nb_freq= 1<<(rdft_bits-1);
832
833     /* compute display index : center on currently output samples */
834     channels = s->audio_st->codec->channels;
835     nb_display_channels = channels;
836     if (!s->paused) {
837         int data_used= s->show_audio==1 ? s->width : (2*nb_freq);
838         n = 2 * channels;
839         delay = audio_write_get_buf_size(s);
840         delay /= n;
841
842         /* to be more precise, we take into account the time spent since
843            the last buffer computation */
844         if (audio_callback_time) {
845             time_diff = av_gettime() - audio_callback_time;
846             delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000;
847         }
848
849         delay += 2*data_used;
850         if (delay < data_used)
851             delay = data_used;
852
853         i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
854         if(s->show_audio==1){
855             h= INT_MIN;
856             for(i=0; i<1000; i+=channels){
857                 int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
858                 int a= s->sample_array[idx];
859                 int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
860                 int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
861                 int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
862                 int score= a-d;
863                 if(h<score && (b^c)<0){
864                     h= score;
865                     i_start= idx;
866                 }
867             }
868         }
869
870         s->last_i_start = i_start;
871     } else {
872         i_start = s->last_i_start;
873     }
874
875     bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
876     if(s->show_audio==1){
877         fill_rectangle(screen,
878                        s->xleft, s->ytop, s->width, s->height,
879                        bgcolor);
880
881         fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
882
883         /* total height for one channel */
884         h = s->height / nb_display_channels;
885         /* graph height / 2 */
886         h2 = (h * 9) / 20;
887         for(ch = 0;ch < nb_display_channels; ch++) {
888             i = i_start + ch;
889             y1 = s->ytop + ch * h + (h / 2); /* position of center line */
890             for(x = 0; x < s->width; x++) {
891                 y = (s->sample_array[i] * h2) >> 15;
892                 if (y < 0) {
893                     y = -y;
894                     ys = y1 - y;
895                 } else {
896                     ys = y1;
897                 }
898                 fill_rectangle(screen,
899                                s->xleft + x, ys, 1, y,
900                                fgcolor);
901                 i += channels;
902                 if (i >= SAMPLE_ARRAY_SIZE)
903                     i -= SAMPLE_ARRAY_SIZE;
904             }
905         }
906
907         fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
908
909         for(ch = 1;ch < nb_display_channels; ch++) {
910             y = s->ytop + ch * h;
911             fill_rectangle(screen,
912                            s->xleft, y, s->width, 1,
913                            fgcolor);
914         }
915         SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
916     }else{
917         nb_display_channels= FFMIN(nb_display_channels, 2);
918         if(rdft_bits != s->rdft_bits){
919             av_rdft_end(s->rdft);
920             s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
921             s->rdft_bits= rdft_bits;
922         }
923         {
924             FFTSample data[2][2*nb_freq];
925             for(ch = 0;ch < nb_display_channels; ch++) {
926                 i = i_start + ch;
927                 for(x = 0; x < 2*nb_freq; x++) {
928                     double w= (x-nb_freq)*(1.0/nb_freq);
929                     data[ch][x]= s->sample_array[i]*(1.0-w*w);
930                     i += channels;
931                     if (i >= SAMPLE_ARRAY_SIZE)
932                         i -= SAMPLE_ARRAY_SIZE;
933                 }
934                 av_rdft_calc(s->rdft, data[ch]);
935             }
936             //least efficient way to do this, we should of course directly access it but its more than fast enough
937             for(y=0; y<s->height; y++){
938                 double w= 1/sqrt(nb_freq);
939                 int a= sqrt(w*sqrt(data[0][2*y+0]*data[0][2*y+0] + data[0][2*y+1]*data[0][2*y+1]));
940                 int b= sqrt(w*sqrt(data[1][2*y+0]*data[1][2*y+0] + data[1][2*y+1]*data[1][2*y+1]));
941                 a= FFMIN(a,255);
942                 b= FFMIN(b,255);
943                 fgcolor = SDL_MapRGB(screen->format, a, b, (a+b)/2);
944
945                 fill_rectangle(screen,
946                             s->xpos, s->height-y, 1, 1,
947                             fgcolor);
948             }
949         }
950         SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
951         s->xpos++;
952         if(s->xpos >= s->width)
953             s->xpos= s->xleft;
954     }
955 }
956
957 static int video_open(VideoState *is){
958     int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
959     int w,h;
960
961     if(is_full_screen) flags |= SDL_FULLSCREEN;
962     else               flags |= SDL_RESIZABLE;
963
964     if (is_full_screen && fs_screen_width) {
965         w = fs_screen_width;
966         h = fs_screen_height;
967     } else if(!is_full_screen && screen_width){
968         w = screen_width;
969         h = screen_height;
970 #if CONFIG_AVFILTER
971     }else if (is->out_video_filter && is->out_video_filter->inputs[0]){
972         w = is->out_video_filter->inputs[0]->w;
973         h = is->out_video_filter->inputs[0]->h;
974 #else
975     }else if (is->video_st && is->video_st->codec->width){
976         w = is->video_st->codec->width;
977         h = is->video_st->codec->height;
978 #endif
979     } else {
980         w = 640;
981         h = 480;
982     }
983     if(screen && is->width == screen->w && screen->w == w
984        && is->height== screen->h && screen->h == h)
985         return 0;
986
987 #ifndef __APPLE__
988     screen = SDL_SetVideoMode(w, h, 0, flags);
989 #else
990     /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
991     screen = SDL_SetVideoMode(w, h, 24, flags);
992 #endif
993     if (!screen) {
994         fprintf(stderr, "SDL: could not set video mode - exiting\n");
995         return -1;
996     }
997     if (!window_title)
998         window_title = input_filename;
999     SDL_WM_SetCaption(window_title, window_title);
1000
1001     is->width = screen->w;
1002     is->height = screen->h;
1003
1004     return 0;
1005 }
1006
1007 /* display the current picture, if any */
1008 static void video_display(VideoState *is)
1009 {
1010     if(!screen)
1011         video_open(cur_stream);
1012     if (is->audio_st && is->show_audio)
1013         video_audio_display(is);
1014     else if (is->video_st)
1015         video_image_display(is);
1016 }
1017
1018 static int refresh_thread(void *opaque)
1019 {
1020     VideoState *is= opaque;
1021     while(!is->abort_request){
1022     SDL_Event event;
1023     event.type = FF_REFRESH_EVENT;
1024     event.user.data1 = opaque;
1025         if(!is->refresh){
1026             is->refresh=1;
1027     SDL_PushEvent(&event);
1028         }
1029         usleep(is->audio_st && is->show_audio ? rdftspeed*1000 : 5000); //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
1030     }
1031     return 0;
1032 }
1033
1034 /* get the current audio clock value */
1035 static double get_audio_clock(VideoState *is)
1036 {
1037     double pts;
1038     int hw_buf_size, bytes_per_sec;
1039     pts = is->audio_clock;
1040     hw_buf_size = audio_write_get_buf_size(is);
1041     bytes_per_sec = 0;
1042     if (is->audio_st) {
1043         bytes_per_sec = is->audio_st->codec->sample_rate *
1044             2 * is->audio_st->codec->channels;
1045     }
1046     if (bytes_per_sec)
1047         pts -= (double)hw_buf_size / bytes_per_sec;
1048     return pts;
1049 }
1050
1051 /* get the current video clock value */
1052 static double get_video_clock(VideoState *is)
1053 {
1054     if (is->paused) {
1055         return is->video_current_pts;
1056     } else {
1057         return is->video_current_pts_drift + av_gettime() / 1000000.0;
1058     }
1059 }
1060
1061 /* get the current external clock value */
1062 static double get_external_clock(VideoState *is)
1063 {
1064     int64_t ti;
1065     ti = av_gettime();
1066     return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
1067 }
1068
1069 /* get the current master clock value */
1070 static double get_master_clock(VideoState *is)
1071 {
1072     double val;
1073
1074     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1075         if (is->video_st)
1076             val = get_video_clock(is);
1077         else
1078             val = get_audio_clock(is);
1079     } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1080         if (is->audio_st)
1081             val = get_audio_clock(is);
1082         else
1083             val = get_video_clock(is);
1084     } else {
1085         val = get_external_clock(is);
1086     }
1087     return val;
1088 }
1089
1090 /* seek in the stream */
1091 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1092 {
1093     if (!is->seek_req) {
1094         is->seek_pos = pos;
1095         is->seek_rel = rel;
1096         is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1097         if (seek_by_bytes)
1098             is->seek_flags |= AVSEEK_FLAG_BYTE;
1099         is->seek_req = 1;
1100     }
1101 }
1102
1103 /* pause or resume the video */
1104 static void stream_pause(VideoState *is)
1105 {
1106     if (is->paused) {
1107         is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
1108         if(is->read_pause_return != AVERROR(ENOSYS)){
1109             is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1110         }
1111         is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1112     }
1113     is->paused = !is->paused;
1114 }
1115
1116 static double compute_target_time(double frame_current_pts, VideoState *is)
1117 {
1118     double delay, sync_threshold, diff;
1119
1120     /* compute nominal delay */
1121     delay = frame_current_pts - is->frame_last_pts;
1122     if (delay <= 0 || delay >= 10.0) {
1123         /* if incorrect delay, use previous one */
1124         delay = is->frame_last_delay;
1125     } else {
1126         is->frame_last_delay = delay;
1127     }
1128     is->frame_last_pts = frame_current_pts;
1129
1130     /* update delay to follow master synchronisation source */
1131     if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1132          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1133         /* if video is slave, we try to correct big delays by
1134            duplicating or deleting a frame */
1135         diff = get_video_clock(is) - get_master_clock(is);
1136
1137         /* skip or repeat frame. We take into account the
1138            delay to compute the threshold. I still don't know
1139            if it is the best guess */
1140         sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1141         if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1142             if (diff <= -sync_threshold)
1143                 delay = 0;
1144             else if (diff >= sync_threshold)
1145                 delay = 2 * delay;
1146         }
1147     }
1148     is->frame_timer += delay;
1149 #if defined(DEBUG_SYNC)
1150     printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1151             delay, actual_delay, frame_current_pts, -diff);
1152 #endif
1153
1154     return is->frame_timer;
1155 }
1156
1157 /* called to display each frame */
1158 static void video_refresh_timer(void *opaque)
1159 {
1160     VideoState *is = opaque;
1161     VideoPicture *vp;
1162
1163     SubPicture *sp, *sp2;
1164
1165     if (is->video_st) {
1166 retry:
1167         if (is->pictq_size == 0) {
1168             //nothing to do, no picture to display in the que
1169         } else {
1170             double time= av_gettime()/1000000.0;
1171             double next_target;
1172             /* dequeue the picture */
1173             vp = &is->pictq[is->pictq_rindex];
1174
1175             if(time < vp->target_clock)
1176                 return;
1177             /* update current video pts */
1178             is->video_current_pts = vp->pts;
1179             is->video_current_pts_drift = is->video_current_pts - time;
1180             is->video_current_pos = vp->pos;
1181             if(is->pictq_size > 1){
1182                 VideoPicture *nextvp= &is->pictq[(is->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE];
1183                 assert(nextvp->target_clock >= vp->target_clock);
1184                 next_target= nextvp->target_clock;
1185             }else{
1186                 next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly
1187             }
1188             if(framedrop && time > next_target){
1189                 is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR;
1190                 if(is->pictq_size > 1 || time > next_target + 0.5){
1191                     /* update queue size and signal for next picture */
1192                     if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1193                         is->pictq_rindex = 0;
1194
1195                     SDL_LockMutex(is->pictq_mutex);
1196                     is->pictq_size--;
1197                     SDL_CondSignal(is->pictq_cond);
1198                     SDL_UnlockMutex(is->pictq_mutex);
1199                     goto retry;
1200                 }
1201             }
1202
1203             if(is->subtitle_st) {
1204                 if (is->subtitle_stream_changed) {
1205                     SDL_LockMutex(is->subpq_mutex);
1206
1207                     while (is->subpq_size) {
1208                         free_subpicture(&is->subpq[is->subpq_rindex]);
1209
1210                         /* update queue size and signal for next picture */
1211                         if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1212                             is->subpq_rindex = 0;
1213
1214                         is->subpq_size--;
1215                     }
1216                     is->subtitle_stream_changed = 0;
1217
1218                     SDL_CondSignal(is->subpq_cond);
1219                     SDL_UnlockMutex(is->subpq_mutex);
1220                 } else {
1221                     if (is->subpq_size > 0) {
1222                         sp = &is->subpq[is->subpq_rindex];
1223
1224                         if (is->subpq_size > 1)
1225                             sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1226                         else
1227                             sp2 = NULL;
1228
1229                         if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1230                                 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1231                         {
1232                             free_subpicture(sp);
1233
1234                             /* update queue size and signal for next picture */
1235                             if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1236                                 is->subpq_rindex = 0;
1237
1238                             SDL_LockMutex(is->subpq_mutex);
1239                             is->subpq_size--;
1240                             SDL_CondSignal(is->subpq_cond);
1241                             SDL_UnlockMutex(is->subpq_mutex);
1242                         }
1243                     }
1244                 }
1245             }
1246
1247             /* display picture */
1248             video_display(is);
1249
1250             /* update queue size and signal for next picture */
1251             if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1252                 is->pictq_rindex = 0;
1253
1254             SDL_LockMutex(is->pictq_mutex);
1255             is->pictq_size--;
1256             SDL_CondSignal(is->pictq_cond);
1257             SDL_UnlockMutex(is->pictq_mutex);
1258         }
1259     } else if (is->audio_st) {
1260         /* draw the next audio frame */
1261
1262         /* if only audio stream, then display the audio bars (better
1263            than nothing, just to test the implementation */
1264
1265         /* display picture */
1266         video_display(is);
1267     }
1268     if (show_status) {
1269         static int64_t last_time;
1270         int64_t cur_time;
1271         int aqsize, vqsize, sqsize;
1272         double av_diff;
1273
1274         cur_time = av_gettime();
1275         if (!last_time || (cur_time - last_time) >= 30000) {
1276             aqsize = 0;
1277             vqsize = 0;
1278             sqsize = 0;
1279             if (is->audio_st)
1280                 aqsize = is->audioq.size;
1281             if (is->video_st)
1282                 vqsize = is->videoq.size;
1283             if (is->subtitle_st)
1284                 sqsize = is->subtitleq.size;
1285             av_diff = 0;
1286             if (is->audio_st && is->video_st)
1287                 av_diff = get_audio_clock(is) - get_video_clock(is);
1288             printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
1289                    get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts);
1290             fflush(stdout);
1291             last_time = cur_time;
1292         }
1293     }
1294 }
1295
1296 /* allocate a picture (needs to do that in main thread to avoid
1297    potential locking problems */
1298 static void alloc_picture(void *opaque)
1299 {
1300     VideoState *is = opaque;
1301     VideoPicture *vp;
1302
1303     vp = &is->pictq[is->pictq_windex];
1304
1305     if (vp->bmp)
1306         SDL_FreeYUVOverlay(vp->bmp);
1307
1308 #if CONFIG_AVFILTER
1309     if (vp->picref)
1310         avfilter_unref_pic(vp->picref);
1311     vp->picref = NULL;
1312
1313     vp->width   = is->out_video_filter->inputs[0]->w;
1314     vp->height  = is->out_video_filter->inputs[0]->h;
1315     vp->pix_fmt = is->out_video_filter->inputs[0]->format;
1316 #else
1317     vp->width   = is->video_st->codec->width;
1318     vp->height  = is->video_st->codec->height;
1319     vp->pix_fmt = is->video_st->codec->pix_fmt;
1320 #endif
1321
1322     vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1323                                    SDL_YV12_OVERLAY,
1324                                    screen);
1325
1326     SDL_LockMutex(is->pictq_mutex);
1327     vp->allocated = 1;
1328     SDL_CondSignal(is->pictq_cond);
1329     SDL_UnlockMutex(is->pictq_mutex);
1330 }
1331
1332 /**
1333  *
1334  * @param pts the dts of the pkt / pts of the frame and guessed if not known
1335  */
1336 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
1337 {
1338     VideoPicture *vp;
1339     int dst_pix_fmt;
1340 #if CONFIG_AVFILTER
1341     AVPicture pict_src;
1342 #endif
1343     /* wait until we have space to put a new picture */
1344     SDL_LockMutex(is->pictq_mutex);
1345
1346     if(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE && !is->refresh)
1347         is->skip_frames= FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0-FRAME_SKIP_FACTOR));
1348
1349     while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1350            !is->videoq.abort_request) {
1351         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1352     }
1353     SDL_UnlockMutex(is->pictq_mutex);
1354
1355     if (is->videoq.abort_request)
1356         return -1;
1357
1358     vp = &is->pictq[is->pictq_windex];
1359
1360     /* alloc or resize hardware picture buffer */
1361     if (!vp->bmp ||
1362 #if CONFIG_AVFILTER
1363         vp->width  != is->out_video_filter->inputs[0]->w ||
1364         vp->height != is->out_video_filter->inputs[0]->h) {
1365 #else
1366         vp->width != is->video_st->codec->width ||
1367         vp->height != is->video_st->codec->height) {
1368 #endif
1369         SDL_Event event;
1370
1371         vp->allocated = 0;
1372
1373         /* the allocation must be done in the main thread to avoid
1374            locking problems */
1375         event.type = FF_ALLOC_EVENT;
1376         event.user.data1 = is;
1377         SDL_PushEvent(&event);
1378
1379         /* wait until the picture is allocated */
1380         SDL_LockMutex(is->pictq_mutex);
1381         while (!vp->allocated && !is->videoq.abort_request) {
1382             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1383         }
1384         SDL_UnlockMutex(is->pictq_mutex);
1385
1386         if (is->videoq.abort_request)
1387             return -1;
1388     }
1389
1390     /* if the frame is not skipped, then display it */
1391     if (vp->bmp) {
1392         AVPicture pict;
1393 #if CONFIG_AVFILTER
1394         if(vp->picref)
1395             avfilter_unref_pic(vp->picref);
1396         vp->picref = src_frame->opaque;
1397 #endif
1398
1399         /* get a pointer on the bitmap */
1400         SDL_LockYUVOverlay (vp->bmp);
1401
1402         dst_pix_fmt = PIX_FMT_YUV420P;
1403         memset(&pict,0,sizeof(AVPicture));
1404         pict.data[0] = vp->bmp->pixels[0];
1405         pict.data[1] = vp->bmp->pixels[2];
1406         pict.data[2] = vp->bmp->pixels[1];
1407
1408         pict.linesize[0] = vp->bmp->pitches[0];
1409         pict.linesize[1] = vp->bmp->pitches[2];
1410         pict.linesize[2] = vp->bmp->pitches[1];
1411
1412 #if CONFIG_AVFILTER
1413         pict_src.data[0] = src_frame->data[0];
1414         pict_src.data[1] = src_frame->data[1];
1415         pict_src.data[2] = src_frame->data[2];
1416
1417         pict_src.linesize[0] = src_frame->linesize[0];
1418         pict_src.linesize[1] = src_frame->linesize[1];
1419         pict_src.linesize[2] = src_frame->linesize[2];
1420
1421         //FIXME use direct rendering
1422         av_picture_copy(&pict, &pict_src,
1423                         vp->pix_fmt, vp->width, vp->height);
1424 #else
1425         sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1426         is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1427             vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
1428             dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1429         if (is->img_convert_ctx == NULL) {
1430             fprintf(stderr, "Cannot initialize the conversion context\n");
1431             exit(1);
1432         }
1433         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1434                   0, vp->height, pict.data, pict.linesize);
1435 #endif
1436         /* update the bitmap content */
1437         SDL_UnlockYUVOverlay(vp->bmp);
1438
1439         vp->pts = pts;
1440         vp->pos = pos;
1441
1442         /* now we can update the picture count */
1443         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1444             is->pictq_windex = 0;
1445         SDL_LockMutex(is->pictq_mutex);
1446         vp->target_clock= compute_target_time(vp->pts, is);
1447
1448         is->pictq_size++;
1449         SDL_UnlockMutex(is->pictq_mutex);
1450     }
1451     return 0;
1452 }
1453
1454 /**
1455  * compute the exact PTS for the picture if it is omitted in the stream
1456  * @param pts1 the dts of the pkt / pts of the frame
1457  */
1458 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1459 {
1460     double frame_delay, pts;
1461
1462     pts = pts1;
1463
1464     if (pts != 0) {
1465         /* update video clock with pts, if present */
1466         is->video_clock = pts;
1467     } else {
1468         pts = is->video_clock;
1469     }
1470     /* update video clock for next frame */
1471     frame_delay = av_q2d(is->video_st->codec->time_base);
1472     /* for MPEG2, the frame can be repeated, so we update the
1473        clock accordingly */
1474     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1475     is->video_clock += frame_delay;
1476
1477 #if defined(DEBUG_SYNC) && 0
1478     printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1479            av_get_pict_type_char(src_frame->pict_type), pts, pts1);
1480 #endif
1481     return queue_picture(is, src_frame, pts, pos);
1482 }
1483
1484 static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
1485 {
1486     int len1, got_picture, i;
1487
1488         if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1489             return -1;
1490
1491         if(pkt->data == flush_pkt.data){
1492             avcodec_flush_buffers(is->video_st->codec);
1493
1494             SDL_LockMutex(is->pictq_mutex);
1495             //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1496             for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){
1497                 is->pictq[i].target_clock= 0;
1498             }
1499             while (is->pictq_size && !is->videoq.abort_request) {
1500                 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1501             }
1502             is->video_current_pos= -1;
1503             SDL_UnlockMutex(is->pictq_mutex);
1504
1505             is->last_dts_for_fault_detection=
1506             is->last_pts_for_fault_detection= INT64_MIN;
1507             is->frame_last_pts= AV_NOPTS_VALUE;
1508             is->frame_last_delay = 0;
1509             is->frame_timer = (double)av_gettime() / 1000000.0;
1510             is->skip_frames= 1;
1511             is->skip_frames_index= 0;
1512             return 0;
1513         }
1514
1515         /* NOTE: ipts is the PTS of the _first_ picture beginning in
1516            this packet, if any */
1517         is->video_st->codec->reordered_opaque= pkt->pts;
1518         len1 = avcodec_decode_video2(is->video_st->codec,
1519                                     frame, &got_picture,
1520                                     pkt);
1521
1522         if (got_picture) {
1523             if(pkt->dts != AV_NOPTS_VALUE){
1524                 is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1525                 is->last_dts_for_fault_detection= pkt->dts;
1526             }
1527             if(frame->reordered_opaque != AV_NOPTS_VALUE){
1528                 is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1529                 is->last_pts_for_fault_detection= frame->reordered_opaque;
1530             }
1531         }
1532
1533         if(   (   decoder_reorder_pts==1
1534                || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
1535                || pkt->dts == AV_NOPTS_VALUE)
1536            && frame->reordered_opaque != AV_NOPTS_VALUE)
1537             *pts= frame->reordered_opaque;
1538         else if(pkt->dts != AV_NOPTS_VALUE)
1539             *pts= pkt->dts;
1540         else
1541             *pts= 0;
1542
1543 //            if (len1 < 0)
1544 //                break;
1545     if (got_picture){
1546         is->skip_frames_index += 1;
1547         if(is->skip_frames_index >= is->skip_frames){
1548             is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
1549             return 1;
1550         }
1551
1552     }
1553     return 0;
1554 }
1555
1556 #if CONFIG_AVFILTER
1557 typedef struct {
1558     VideoState *is;
1559     AVFrame *frame;
1560     int use_dr1;
1561 } FilterPriv;
1562
1563 static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
1564 {
1565     AVFilterContext *ctx = codec->opaque;
1566     AVFilterPicRef  *ref;
1567     int perms = AV_PERM_WRITE;
1568     int i, w, h, stride[4];
1569     unsigned edge;
1570
1571     if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
1572         if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
1573         if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
1574         if(pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
1575     }
1576     if(pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
1577
1578     w = codec->width;
1579     h = codec->height;
1580     avcodec_align_dimensions2(codec, &w, &h, stride);
1581     edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
1582     w += edge << 1;
1583     h += edge << 1;
1584
1585     if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
1586         return -1;
1587
1588     ref->w = codec->width;
1589     ref->h = codec->height;
1590     for(i = 0; i < 3; i ++) {
1591         unsigned hshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_w;
1592         unsigned vshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_h;
1593
1594         if (ref->data[i]) {
1595             ref->data[i]    += (edge >> hshift) + ((edge * ref->linesize[i]) >> vshift);
1596         }
1597         pic->data[i]     = ref->data[i];
1598         pic->linesize[i] = ref->linesize[i];
1599     }
1600     pic->opaque = ref;
1601     pic->age    = INT_MAX;
1602     pic->type   = FF_BUFFER_TYPE_USER;
1603     return 0;
1604 }
1605
1606 static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
1607 {
1608     memset(pic->data, 0, sizeof(pic->data));
1609     avfilter_unref_pic(pic->opaque);
1610 }
1611
1612 static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
1613 {
1614     AVFilterPicRef *ref = pic->opaque;
1615
1616     if (pic->data[0] == NULL) {
1617         pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
1618         return codec->get_buffer(codec, pic);
1619     }
1620
1621     if ((codec->width != ref->w) || (codec->height != ref->h) ||
1622         (codec->pix_fmt != ref->pic->format)) {
1623         av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
1624         return -1;
1625     }
1626
1627     pic->reordered_opaque = codec->reordered_opaque;
1628     return 0;
1629 }
1630
1631 static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
1632 {
1633     FilterPriv *priv = ctx->priv;
1634     AVCodecContext *codec;
1635     if(!opaque) return -1;
1636
1637     priv->is = opaque;
1638     codec    = priv->is->video_st->codec;
1639     codec->opaque = ctx;
1640     if(codec->codec->capabilities & CODEC_CAP_DR1) {
1641         priv->use_dr1 = 1;
1642         codec->get_buffer     = input_get_buffer;
1643         codec->release_buffer = input_release_buffer;
1644         codec->reget_buffer   = input_reget_buffer;
1645     }
1646
1647     priv->frame = avcodec_alloc_frame();
1648
1649     return 0;
1650 }
1651
1652 static void input_uninit(AVFilterContext *ctx)
1653 {
1654     FilterPriv *priv = ctx->priv;
1655     av_free(priv->frame);
1656 }
1657
1658 static int input_request_frame(AVFilterLink *link)
1659 {
1660     FilterPriv *priv = link->src->priv;
1661     AVFilterPicRef *picref;
1662     int64_t pts = 0;
1663     AVPacket pkt;
1664     int ret;
1665
1666     while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
1667         av_free_packet(&pkt);
1668     if (ret < 0)
1669         return -1;
1670
1671     if(priv->use_dr1) {
1672         picref = avfilter_ref_pic(priv->frame->opaque, ~0);
1673     } else {
1674         picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
1675         av_picture_copy((AVPicture *)&picref->data, (AVPicture *)priv->frame,
1676                         picref->pic->format, link->w, link->h);
1677     }
1678     av_free_packet(&pkt);
1679
1680     picref->pts = pts;
1681     picref->pos = pkt.pos;
1682     picref->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio;
1683     avfilter_start_frame(link, picref);
1684     avfilter_draw_slice(link, 0, link->h, 1);
1685     avfilter_end_frame(link);
1686
1687     return 0;
1688 }
1689
1690 static int input_query_formats(AVFilterContext *ctx)
1691 {
1692     FilterPriv *priv = ctx->priv;
1693     enum PixelFormat pix_fmts[] = {
1694         priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
1695     };
1696
1697     avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1698     return 0;
1699 }
1700
1701 static int input_config_props(AVFilterLink *link)
1702 {
1703     FilterPriv *priv  = link->src->priv;
1704     AVCodecContext *c = priv->is->video_st->codec;
1705
1706     link->w = c->width;
1707     link->h = c->height;
1708
1709     return 0;
1710 }
1711
1712 static AVFilter input_filter =
1713 {
1714     .name      = "ffplay_input",
1715
1716     .priv_size = sizeof(FilterPriv),
1717
1718     .init      = input_init,
1719     .uninit    = input_uninit,
1720
1721     .query_formats = input_query_formats,
1722
1723     .inputs    = (AVFilterPad[]) {{ .name = NULL }},
1724     .outputs   = (AVFilterPad[]) {{ .name = "default",
1725                                     .type = AVMEDIA_TYPE_VIDEO,
1726                                     .request_frame = input_request_frame,
1727                                     .config_props  = input_config_props, },
1728                                   { .name = NULL }},
1729 };
1730
1731 static void output_end_frame(AVFilterLink *link)
1732 {
1733 }
1734
1735 static int output_query_formats(AVFilterContext *ctx)
1736 {
1737     enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
1738
1739     avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1740     return 0;
1741 }
1742
1743 static int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
1744                                     int64_t *pts, int64_t *pos)
1745 {
1746     AVFilterPicRef *pic;
1747
1748     if(avfilter_request_frame(ctx->inputs[0]))
1749         return -1;
1750     if(!(pic = ctx->inputs[0]->cur_pic))
1751         return -1;
1752     ctx->inputs[0]->cur_pic = NULL;
1753
1754     frame->opaque = pic;
1755     *pts          = pic->pts;
1756     *pos          = pic->pos;
1757
1758     memcpy(frame->data,     pic->data,     sizeof(frame->data));
1759     memcpy(frame->linesize, pic->linesize, sizeof(frame->linesize));
1760
1761     return 1;
1762 }
1763
1764 static AVFilter output_filter =
1765 {
1766     .name      = "ffplay_output",
1767
1768     .query_formats = output_query_formats,
1769
1770     .inputs    = (AVFilterPad[]) {{ .name          = "default",
1771                                     .type          = AVMEDIA_TYPE_VIDEO,
1772                                     .end_frame     = output_end_frame,
1773                                     .min_perms     = AV_PERM_READ, },
1774                                   { .name = NULL }},
1775     .outputs   = (AVFilterPad[]) {{ .name = NULL }},
1776 };
1777 #endif  /* CONFIG_AVFILTER */
1778
1779 static int video_thread(void *arg)
1780 {
1781     VideoState *is = arg;
1782     AVFrame *frame= avcodec_alloc_frame();
1783     int64_t pts_int;
1784     double pts;
1785     int ret;
1786
1787 #if CONFIG_AVFILTER
1788     int64_t pos;
1789     char sws_flags_str[128];
1790     AVFilterContext *filt_src = NULL, *filt_out = NULL;
1791     AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph));
1792     snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
1793     graph->scale_sws_opts = av_strdup(sws_flags_str);
1794
1795     if(!(filt_src = avfilter_open(&input_filter,  "src")))   goto the_end;
1796     if(!(filt_out = avfilter_open(&output_filter, "out")))   goto the_end;
1797
1798     if(avfilter_init_filter(filt_src, NULL, is))             goto the_end;
1799     if(avfilter_init_filter(filt_out, NULL, frame))          goto the_end;
1800
1801
1802     if(vfilters) {
1803         AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
1804         AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));
1805
1806         outputs->name    = av_strdup("in");
1807         outputs->filter  = filt_src;
1808         outputs->pad_idx = 0;
1809         outputs->next    = NULL;
1810
1811         inputs->name    = av_strdup("out");
1812         inputs->filter  = filt_out;
1813         inputs->pad_idx = 0;
1814         inputs->next    = NULL;
1815
1816         if (avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL) < 0)
1817             goto the_end;
1818         av_freep(&vfilters);
1819     } else {
1820         if(avfilter_link(filt_src, 0, filt_out, 0) < 0)          goto the_end;
1821     }
1822     avfilter_graph_add_filter(graph, filt_src);
1823     avfilter_graph_add_filter(graph, filt_out);
1824
1825     if(avfilter_graph_check_validity(graph, NULL))           goto the_end;
1826     if(avfilter_graph_config_formats(graph, NULL))           goto the_end;
1827     if(avfilter_graph_config_links(graph, NULL))             goto the_end;
1828
1829     is->out_video_filter = filt_out;
1830 #endif
1831
1832     for(;;) {
1833 #if !CONFIG_AVFILTER
1834         AVPacket pkt;
1835 #endif
1836         while (is->paused && !is->videoq.abort_request)
1837             SDL_Delay(10);
1838 #if CONFIG_AVFILTER
1839         ret = get_filtered_video_frame(filt_out, frame, &pts_int, &pos);
1840 #else
1841         ret = get_video_frame(is, frame, &pts_int, &pkt);
1842 #endif
1843
1844         if (ret < 0) goto the_end;
1845
1846         if (!ret)
1847             continue;
1848
1849         pts = pts_int*av_q2d(is->video_st->time_base);
1850
1851 #if CONFIG_AVFILTER
1852         ret = output_picture2(is, frame, pts, pos);
1853 #else
1854         ret = output_picture2(is, frame, pts,  pkt.pos);
1855         av_free_packet(&pkt);
1856 #endif
1857         if (ret < 0)
1858             goto the_end;
1859
1860         if (step)
1861             if (cur_stream)
1862                 stream_pause(cur_stream);
1863     }
1864  the_end:
1865 #if CONFIG_AVFILTER
1866     avfilter_graph_destroy(graph);
1867     av_freep(&graph);
1868 #endif
1869     av_free(frame);
1870     return 0;
1871 }
1872
1873 static int subtitle_thread(void *arg)
1874 {
1875     VideoState *is = arg;
1876     SubPicture *sp;
1877     AVPacket pkt1, *pkt = &pkt1;
1878     int len1, got_subtitle;
1879     double pts;
1880     int i, j;
1881     int r, g, b, y, u, v, a;
1882
1883     for(;;) {
1884         while (is->paused && !is->subtitleq.abort_request) {
1885             SDL_Delay(10);
1886         }
1887         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1888             break;
1889
1890         if(pkt->data == flush_pkt.data){
1891             avcodec_flush_buffers(is->subtitle_st->codec);
1892             continue;
1893         }
1894         SDL_LockMutex(is->subpq_mutex);
1895         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1896                !is->subtitleq.abort_request) {
1897             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1898         }
1899         SDL_UnlockMutex(is->subpq_mutex);
1900
1901         if (is->subtitleq.abort_request)
1902             goto the_end;
1903
1904         sp = &is->subpq[is->subpq_windex];
1905
1906        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1907            this packet, if any */
1908         pts = 0;
1909         if (pkt->pts != AV_NOPTS_VALUE)
1910             pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1911
1912         len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1913                                     &sp->sub, &got_subtitle,
1914                                     pkt);
1915 //            if (len1 < 0)
1916 //                break;
1917         if (got_subtitle && sp->sub.format == 0) {
1918             sp->pts = pts;
1919
1920             for (i = 0; i < sp->sub.num_rects; i++)
1921             {
1922                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1923                 {
1924                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1925                     y = RGB_TO_Y_CCIR(r, g, b);
1926                     u = RGB_TO_U_CCIR(r, g, b, 0);
1927                     v = RGB_TO_V_CCIR(r, g, b, 0);
1928                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1929                 }
1930             }
1931
1932             /* now we can update the picture count */
1933             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1934                 is->subpq_windex = 0;
1935             SDL_LockMutex(is->subpq_mutex);
1936             is->subpq_size++;
1937             SDL_UnlockMutex(is->subpq_mutex);
1938         }
1939         av_free_packet(pkt);
1940 //        if (step)
1941 //            if (cur_stream)
1942 //                stream_pause(cur_stream);
1943     }
1944  the_end:
1945     return 0;
1946 }
1947
1948 /* copy samples for viewing in editor window */
1949 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1950 {
1951     int size, len, channels;
1952
1953     channels = is->audio_st->codec->channels;
1954
1955     size = samples_size / sizeof(short);
1956     while (size > 0) {
1957         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1958         if (len > size)
1959             len = size;
1960         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1961         samples += len;
1962         is->sample_array_index += len;
1963         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1964             is->sample_array_index = 0;
1965         size -= len;
1966     }
1967 }
1968
1969 /* return the new audio buffer size (samples can be added or deleted
1970    to get better sync if video or external master clock) */
1971 static int synchronize_audio(VideoState *is, short *samples,
1972                              int samples_size1, double pts)
1973 {
1974     int n, samples_size;
1975     double ref_clock;
1976
1977     n = 2 * is->audio_st->codec->channels;
1978     samples_size = samples_size1;
1979
1980     /* if not master, then we try to remove or add samples to correct the clock */
1981     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1982          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1983         double diff, avg_diff;
1984         int wanted_size, min_size, max_size, nb_samples;
1985
1986         ref_clock = get_master_clock(is);
1987         diff = get_audio_clock(is) - ref_clock;
1988
1989         if (diff < AV_NOSYNC_THRESHOLD) {
1990             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1991             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1992                 /* not enough measures to have a correct estimate */
1993                 is->audio_diff_avg_count++;
1994             } else {
1995                 /* estimate the A-V difference */
1996                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1997
1998                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1999                     wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
2000                     nb_samples = samples_size / n;
2001
2002                     min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
2003                     max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
2004                     if (wanted_size < min_size)
2005                         wanted_size = min_size;
2006                     else if (wanted_size > max_size)
2007                         wanted_size = max_size;
2008
2009                     /* add or remove samples to correction the synchro */
2010                     if (wanted_size < samples_size) {
2011                         /* remove samples */
2012                         samples_size = wanted_size;
2013                     } else if (wanted_size > samples_size) {
2014                         uint8_t *samples_end, *q;
2015                         int nb;
2016
2017                         /* add samples */
2018                         nb = (samples_size - wanted_size);
2019                         samples_end = (uint8_t *)samples + samples_size - n;
2020                         q = samples_end + n;
2021                         while (nb > 0) {
2022                             memcpy(q, samples_end, n);
2023                             q += n;
2024                             nb -= n;
2025                         }
2026                         samples_size = wanted_size;
2027                     }
2028                 }
2029 #if 0
2030                 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
2031                        diff, avg_diff, samples_size - samples_size1,
2032                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
2033 #endif
2034             }
2035         } else {
2036             /* too big difference : may be initial PTS errors, so
2037                reset A-V filter */
2038             is->audio_diff_avg_count = 0;
2039             is->audio_diff_cum = 0;
2040         }
2041     }
2042
2043     return samples_size;
2044 }
2045
2046 /* decode one audio frame and returns its uncompressed size */
2047 static int audio_decode_frame(VideoState *is, double *pts_ptr)
2048 {
2049     AVPacket *pkt_temp = &is->audio_pkt_temp;
2050     AVPacket *pkt = &is->audio_pkt;
2051     AVCodecContext *dec= is->audio_st->codec;
2052     int n, len1, data_size;
2053     double pts;
2054
2055     for(;;) {
2056         /* NOTE: the audio packet can contain several frames */
2057         while (pkt_temp->size > 0) {
2058             data_size = sizeof(is->audio_buf1);
2059             len1 = avcodec_decode_audio3(dec,
2060                                         (int16_t *)is->audio_buf1, &data_size,
2061                                         pkt_temp);
2062             if (len1 < 0) {
2063                 /* if error, we skip the frame */
2064                 pkt_temp->size = 0;
2065                 break;
2066             }
2067
2068             pkt_temp->data += len1;
2069             pkt_temp->size -= len1;
2070             if (data_size <= 0)
2071                 continue;
2072
2073             if (dec->sample_fmt != is->audio_src_fmt) {
2074                 if (is->reformat_ctx)
2075                     av_audio_convert_free(is->reformat_ctx);
2076                 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
2077                                                          dec->sample_fmt, 1, NULL, 0);
2078                 if (!is->reformat_ctx) {
2079                     fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
2080                         avcodec_get_sample_fmt_name(dec->sample_fmt),
2081                         avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
2082                         break;
2083                 }
2084                 is->audio_src_fmt= dec->sample_fmt;
2085             }
2086
2087             if (is->reformat_ctx) {
2088                 const void *ibuf[6]= {is->audio_buf1};
2089                 void *obuf[6]= {is->audio_buf2};
2090                 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
2091                 int ostride[6]= {2};
2092                 int len= data_size/istride[0];
2093                 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
2094                     printf("av_audio_convert() failed\n");
2095                     break;
2096                 }
2097                 is->audio_buf= is->audio_buf2;
2098                 /* FIXME: existing code assume that data_size equals framesize*channels*2
2099                           remove this legacy cruft */
2100                 data_size= len*2;
2101             }else{
2102                 is->audio_buf= is->audio_buf1;
2103             }
2104
2105             /* if no pts, then compute it */
2106             pts = is->audio_clock;
2107             *pts_ptr = pts;
2108             n = 2 * dec->channels;
2109             is->audio_clock += (double)data_size /
2110                 (double)(n * dec->sample_rate);
2111 #if defined(DEBUG_SYNC)
2112             {
2113                 static double last_clock;
2114                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
2115                        is->audio_clock - last_clock,
2116                        is->audio_clock, pts);
2117                 last_clock = is->audio_clock;
2118             }
2119 #endif
2120             return data_size;
2121         }
2122
2123         /* free the current packet */
2124         if (pkt->data)
2125             av_free_packet(pkt);
2126
2127         if (is->paused || is->audioq.abort_request) {
2128             return -1;
2129         }
2130
2131         /* read next packet */
2132         if (packet_queue_get(&is->audioq, pkt, 1) < 0)
2133             return -1;
2134         if(pkt->data == flush_pkt.data){
2135             avcodec_flush_buffers(dec);
2136             continue;
2137         }
2138
2139         pkt_temp->data = pkt->data;
2140         pkt_temp->size = pkt->size;
2141
2142         /* if update the audio clock with the pts */
2143         if (pkt->pts != AV_NOPTS_VALUE) {
2144             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
2145         }
2146     }
2147 }
2148
2149 /* get the current audio output buffer size, in samples. With SDL, we
2150    cannot have a precise information */
2151 static int audio_write_get_buf_size(VideoState *is)
2152 {
2153     return is->audio_buf_size - is->audio_buf_index;
2154 }
2155
2156
2157 /* prepare a new audio buffer */
2158 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2159 {
2160     VideoState *is = opaque;
2161     int audio_size, len1;
2162     double pts;
2163
2164     audio_callback_time = av_gettime();
2165
2166     while (len > 0) {
2167         if (is->audio_buf_index >= is->audio_buf_size) {
2168            audio_size = audio_decode_frame(is, &pts);
2169            if (audio_size < 0) {
2170                 /* if error, just output silence */
2171                is->audio_buf = is->audio_buf1;
2172                is->audio_buf_size = 1024;
2173                memset(is->audio_buf, 0, is->audio_buf_size);
2174            } else {
2175                if (is->show_audio)
2176                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2177                audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
2178                                               pts);
2179                is->audio_buf_size = audio_size;
2180            }
2181            is->audio_buf_index = 0;
2182         }
2183         len1 = is->audio_buf_size - is->audio_buf_index;
2184         if (len1 > len)
2185             len1 = len;
2186         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2187         len -= len1;
2188         stream += len1;
2189         is->audio_buf_index += len1;
2190     }
2191 }
2192
2193 /* open a given stream. Return 0 if OK */
2194 static int stream_component_open(VideoState *is, int stream_index)
2195 {
2196     AVFormatContext *ic = is->ic;
2197     AVCodecContext *avctx;
2198     AVCodec *codec;
2199     SDL_AudioSpec wanted_spec, spec;
2200
2201     if (stream_index < 0 || stream_index >= ic->nb_streams)
2202         return -1;
2203     avctx = ic->streams[stream_index]->codec;
2204
2205     /* prepare audio output */
2206     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2207         if (avctx->channels > 0) {
2208             avctx->request_channels = FFMIN(2, avctx->channels);
2209         } else {
2210             avctx->request_channels = 2;
2211         }
2212     }
2213
2214     codec = avcodec_find_decoder(avctx->codec_id);
2215     avctx->debug_mv = debug_mv;
2216     avctx->debug = debug;
2217     avctx->workaround_bugs = workaround_bugs;
2218     avctx->lowres = lowres;
2219     if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2220     avctx->idct_algo= idct;
2221     if(fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2222     avctx->skip_frame= skip_frame;
2223     avctx->skip_idct= skip_idct;
2224     avctx->skip_loop_filter= skip_loop_filter;
2225     avctx->error_recognition= error_recognition;
2226     avctx->error_concealment= error_concealment;
2227     avcodec_thread_init(avctx, thread_count);
2228
2229     set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0);
2230
2231     if (!codec ||
2232         avcodec_open(avctx, codec) < 0)
2233         return -1;
2234
2235     /* prepare audio output */
2236     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2237         wanted_spec.freq = avctx->sample_rate;
2238         wanted_spec.format = AUDIO_S16SYS;
2239         wanted_spec.channels = avctx->channels;
2240         wanted_spec.silence = 0;
2241         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2242         wanted_spec.callback = sdl_audio_callback;
2243         wanted_spec.userdata = is;
2244         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2245             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
2246             return -1;
2247         }
2248         is->audio_hw_buf_size = spec.size;
2249         is->audio_src_fmt= SAMPLE_FMT_S16;
2250     }
2251
2252     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2253     switch(avctx->codec_type) {
2254     case AVMEDIA_TYPE_AUDIO:
2255         is->audio_stream = stream_index;
2256         is->audio_st = ic->streams[stream_index];
2257         is->audio_buf_size = 0;
2258         is->audio_buf_index = 0;
2259
2260         /* init averaging filter */
2261         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2262         is->audio_diff_avg_count = 0;
2263         /* since we do not have a precise anough audio fifo fullness,
2264            we correct audio sync only if larger than this threshold */
2265         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
2266
2267         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2268         packet_queue_init(&is->audioq);
2269         SDL_PauseAudio(0);
2270         break;
2271     case AVMEDIA_TYPE_VIDEO:
2272         is->video_stream = stream_index;
2273         is->video_st = ic->streams[stream_index];
2274
2275 //        is->video_current_pts_time = av_gettime();
2276
2277         packet_queue_init(&is->videoq);
2278         is->video_tid = SDL_CreateThread(video_thread, is);
2279         break;
2280     case AVMEDIA_TYPE_SUBTITLE:
2281         is->subtitle_stream = stream_index;
2282         is->subtitle_st = ic->streams[stream_index];
2283         packet_queue_init(&is->subtitleq);
2284
2285         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2286         break;
2287     default:
2288         break;
2289     }
2290     return 0;
2291 }
2292
2293 static void stream_component_close(VideoState *is, int stream_index)
2294 {
2295     AVFormatContext *ic = is->ic;
2296     AVCodecContext *avctx;
2297
2298     if (stream_index < 0 || stream_index >= ic->nb_streams)
2299         return;
2300     avctx = ic->streams[stream_index]->codec;
2301
2302     switch(avctx->codec_type) {
2303     case AVMEDIA_TYPE_AUDIO:
2304         packet_queue_abort(&is->audioq);
2305
2306         SDL_CloseAudio();
2307
2308         packet_queue_end(&is->audioq);
2309         if (is->reformat_ctx)
2310             av_audio_convert_free(is->reformat_ctx);
2311         is->reformat_ctx = NULL;
2312         break;
2313     case AVMEDIA_TYPE_VIDEO:
2314         packet_queue_abort(&is->videoq);
2315
2316         /* note: we also signal this mutex to make sure we deblock the
2317            video thread in all cases */
2318         SDL_LockMutex(is->pictq_mutex);
2319         SDL_CondSignal(is->pictq_cond);
2320         SDL_UnlockMutex(is->pictq_mutex);
2321
2322         SDL_WaitThread(is->video_tid, NULL);
2323
2324         packet_queue_end(&is->videoq);
2325         break;
2326     case AVMEDIA_TYPE_SUBTITLE:
2327         packet_queue_abort(&is->subtitleq);
2328
2329         /* note: we also signal this mutex to make sure we deblock the
2330            video thread in all cases */
2331         SDL_LockMutex(is->subpq_mutex);
2332         is->subtitle_stream_changed = 1;
2333
2334         SDL_CondSignal(is->subpq_cond);
2335         SDL_UnlockMutex(is->subpq_mutex);
2336
2337         SDL_WaitThread(is->subtitle_tid, NULL);
2338
2339         packet_queue_end(&is->subtitleq);
2340         break;
2341     default:
2342         break;
2343     }
2344
2345     ic->streams[stream_index]->discard = AVDISCARD_ALL;
2346     avcodec_close(avctx);
2347     switch(avctx->codec_type) {
2348     case AVMEDIA_TYPE_AUDIO:
2349         is->audio_st = NULL;
2350         is->audio_stream = -1;
2351         break;
2352     case AVMEDIA_TYPE_VIDEO:
2353         is->video_st = NULL;
2354         is->video_stream = -1;
2355         break;
2356     case AVMEDIA_TYPE_SUBTITLE:
2357         is->subtitle_st = NULL;
2358         is->subtitle_stream = -1;
2359         break;
2360     default:
2361         break;
2362     }
2363 }
2364
2365 /* since we have only one decoding thread, we can use a global
2366    variable instead of a thread local variable */
2367 static VideoState *global_video_state;
2368
2369 static int decode_interrupt_cb(void)
2370 {
2371     return (global_video_state && global_video_state->abort_request);
2372 }
2373
2374 /* this thread gets the stream from the disk or the network */
2375 static int decode_thread(void *arg)
2376 {
2377     VideoState *is = arg;
2378     AVFormatContext *ic;
2379     int err, i, ret;
2380     int st_index[AVMEDIA_TYPE_NB];
2381     int st_count[AVMEDIA_TYPE_NB]={0};
2382     int st_best_packet_count[AVMEDIA_TYPE_NB];
2383     AVPacket pkt1, *pkt = &pkt1;
2384     AVFormatParameters params, *ap = &params;
2385     int eof=0;
2386     int pkt_in_play_range = 0;
2387
2388     ic = avformat_alloc_context();
2389
2390     memset(st_index, -1, sizeof(st_index));
2391     memset(st_best_packet_count, -1, sizeof(st_best_packet_count));
2392     is->video_stream = -1;
2393     is->audio_stream = -1;
2394     is->subtitle_stream = -1;
2395
2396     global_video_state = is;
2397     url_set_interrupt_cb(decode_interrupt_cb);
2398
2399     memset(ap, 0, sizeof(*ap));
2400
2401     ap->prealloced_context = 1;
2402     ap->width = frame_width;
2403     ap->height= frame_height;
2404     ap->time_base= (AVRational){1, 25};
2405     ap->pix_fmt = frame_pix_fmt;
2406
2407     set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
2408
2409     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
2410     if (err < 0) {
2411         print_error(is->filename, err);
2412         ret = -1;
2413         goto fail;
2414     }
2415     is->ic = ic;
2416
2417     if(genpts)
2418         ic->flags |= AVFMT_FLAG_GENPTS;
2419
2420     err = av_find_stream_info(ic);
2421     if (err < 0) {
2422         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2423         ret = -1;
2424         goto fail;
2425     }
2426     if(ic->pb)
2427         ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
2428
2429     if(seek_by_bytes<0)
2430         seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
2431
2432     /* if seeking requested, we execute it */
2433     if (start_time != AV_NOPTS_VALUE) {
2434         int64_t timestamp;
2435
2436         timestamp = start_time;
2437         /* add the stream start time */
2438         if (ic->start_time != AV_NOPTS_VALUE)
2439             timestamp += ic->start_time;
2440         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2441         if (ret < 0) {
2442             fprintf(stderr, "%s: could not seek to position %0.3f\n",
2443                     is->filename, (double)timestamp / AV_TIME_BASE);
2444         }
2445     }
2446
2447     for(i = 0; i < ic->nb_streams; i++) {
2448         AVStream *st= ic->streams[i];
2449         AVCodecContext *avctx = st->codec;
2450         ic->streams[i]->discard = AVDISCARD_ALL;
2451         if(avctx->codec_type >= (unsigned)AVMEDIA_TYPE_NB)
2452             continue;
2453         if(st_count[avctx->codec_type]++ != wanted_stream[avctx->codec_type] && wanted_stream[avctx->codec_type] >= 0)
2454             continue;
2455
2456         if(st_best_packet_count[avctx->codec_type] >= st->codec_info_nb_frames)
2457             continue;
2458         st_best_packet_count[avctx->codec_type]= st->codec_info_nb_frames;
2459
2460         switch(avctx->codec_type) {
2461         case AVMEDIA_TYPE_AUDIO:
2462             if (!audio_disable)
2463                 st_index[AVMEDIA_TYPE_AUDIO] = i;
2464             break;
2465         case AVMEDIA_TYPE_VIDEO:
2466         case AVMEDIA_TYPE_SUBTITLE:
2467             if (!video_disable)
2468                 st_index[avctx->codec_type] = i;
2469             break;
2470         default:
2471             break;
2472         }
2473     }
2474     if (show_status) {
2475         dump_format(ic, 0, is->filename, 0);
2476     }
2477
2478     /* open the streams */
2479     if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2480         stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2481     }
2482
2483     ret=-1;
2484     if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2485         ret= stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2486     }
2487     is->refresh_tid = SDL_CreateThread(refresh_thread, is);
2488     if(ret<0) {
2489         if (!display_disable)
2490             is->show_audio = 2;
2491     }
2492
2493     if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2494         stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2495     }
2496
2497     if (is->video_stream < 0 && is->audio_stream < 0) {
2498         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2499         ret = -1;
2500         goto fail;
2501     }
2502
2503     for(;;) {
2504         if (is->abort_request)
2505             break;
2506         if (is->paused != is->last_paused) {
2507             is->last_paused = is->paused;
2508             if (is->paused)
2509                 is->read_pause_return= av_read_pause(ic);
2510             else
2511                 av_read_play(ic);
2512         }
2513 #if CONFIG_RTSP_DEMUXER
2514         if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2515             /* wait 10 ms to avoid trying to get another packet */
2516             /* XXX: horrible */
2517             SDL_Delay(10);
2518             continue;
2519         }
2520 #endif
2521         if (is->seek_req) {
2522             int64_t seek_target= is->seek_pos;
2523             int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2524             int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2525 //FIXME the +-2 is due to rounding being not done in the correct direction in generation
2526 //      of the seek_pos/seek_rel variables
2527
2528             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2529             if (ret < 0) {
2530                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2531             }else{
2532                 if (is->audio_stream >= 0) {
2533                     packet_queue_flush(&is->audioq);
2534                     packet_queue_put(&is->audioq, &flush_pkt);
2535                 }
2536                 if (is->subtitle_stream >= 0) {
2537                     packet_queue_flush(&is->subtitleq);
2538                     packet_queue_put(&is->subtitleq, &flush_pkt);
2539                 }
2540                 if (is->video_stream >= 0) {
2541                     packet_queue_flush(&is->videoq);
2542                     packet_queue_put(&is->videoq, &flush_pkt);
2543                 }
2544             }
2545             is->seek_req = 0;
2546             eof= 0;
2547         }
2548
2549         /* if the queue are full, no need to read more */
2550         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2551             || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2552                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2553                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2554             /* wait 10 ms */
2555             SDL_Delay(10);
2556             continue;
2557         }
2558         if(url_feof(ic->pb) || eof) {
2559             if(is->video_stream >= 0){
2560                 av_init_packet(pkt);
2561                 pkt->data=NULL;
2562                 pkt->size=0;
2563                 pkt->stream_index= is->video_stream;
2564                 packet_queue_put(&is->videoq, pkt);
2565             }
2566             SDL_Delay(10);
2567             if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){
2568                 if(loop!=1 && (!loop || --loop)){
2569                     stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2570                 }else if(autoexit){
2571                     ret=AVERROR_EOF;
2572                     goto fail;
2573                 }
2574             }
2575             continue;
2576         }
2577         ret = av_read_frame(ic, pkt);
2578         if (ret < 0) {
2579             if (ret == AVERROR_EOF)
2580                 eof=1;
2581             if (url_ferror(ic->pb))
2582                 break;
2583             SDL_Delay(100); /* wait for user event */
2584             continue;
2585         }
2586         /* check if packet is in play range specified by user, then queue, otherwise discard */
2587         pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2588                 (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
2589                 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2590                 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0)/1000000
2591                 <= ((double)duration/1000000);
2592         if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2593             packet_queue_put(&is->audioq, pkt);
2594         } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
2595             packet_queue_put(&is->videoq, pkt);
2596         } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2597             packet_queue_put(&is->subtitleq, pkt);
2598         } else {
2599             av_free_packet(pkt);
2600         }
2601     }
2602     /* wait until the end */
2603     while (!is->abort_request) {
2604         SDL_Delay(100);
2605     }
2606
2607     ret = 0;
2608  fail:
2609     /* disable interrupting */
2610     global_video_state = NULL;
2611
2612     /* close each stream */
2613     if (is->audio_stream >= 0)
2614         stream_component_close(is, is->audio_stream);
2615     if (is->video_stream >= 0)
2616         stream_component_close(is, is->video_stream);
2617     if (is->subtitle_stream >= 0)
2618         stream_component_close(is, is->subtitle_stream);
2619     if (is->ic) {
2620         av_close_input_file(is->ic);
2621         is->ic = NULL; /* safety */
2622     }
2623     url_set_interrupt_cb(NULL);
2624
2625     if (ret != 0) {
2626         SDL_Event event;
2627
2628         event.type = FF_QUIT_EVENT;
2629         event.user.data1 = is;
2630         SDL_PushEvent(&event);
2631     }
2632     return 0;
2633 }
2634
2635 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2636 {
2637     VideoState *is;
2638
2639     is = av_mallocz(sizeof(VideoState));
2640     if (!is)
2641         return NULL;
2642     av_strlcpy(is->filename, filename, sizeof(is->filename));
2643     is->iformat = iformat;
2644     is->ytop = 0;
2645     is->xleft = 0;
2646
2647     /* start video display */
2648     is->pictq_mutex = SDL_CreateMutex();
2649     is->pictq_cond = SDL_CreateCond();
2650
2651     is->subpq_mutex = SDL_CreateMutex();
2652     is->subpq_cond = SDL_CreateCond();
2653
2654     is->av_sync_type = av_sync_type;
2655     is->parse_tid = SDL_CreateThread(decode_thread, is);
2656     if (!is->parse_tid) {
2657         av_free(is);
2658         return NULL;
2659     }
2660     return is;
2661 }
2662
2663 static void stream_close(VideoState *is)
2664 {
2665     VideoPicture *vp;
2666     int i;
2667     /* XXX: use a special url_shutdown call to abort parse cleanly */
2668     is->abort_request = 1;
2669     SDL_WaitThread(is->parse_tid, NULL);
2670     SDL_WaitThread(is->refresh_tid, NULL);
2671
2672     /* free all pictures */
2673     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2674         vp = &is->pictq[i];
2675 #if CONFIG_AVFILTER
2676         if (vp->picref) {
2677             avfilter_unref_pic(vp->picref);
2678             vp->picref = NULL;
2679         }
2680 #endif
2681         if (vp->bmp) {
2682             SDL_FreeYUVOverlay(vp->bmp);
2683             vp->bmp = NULL;
2684         }
2685     }
2686     SDL_DestroyMutex(is->pictq_mutex);
2687     SDL_DestroyCond(is->pictq_cond);
2688     SDL_DestroyMutex(is->subpq_mutex);
2689     SDL_DestroyCond(is->subpq_cond);
2690 #if !CONFIG_AVFILTER
2691     if (is->img_convert_ctx)
2692         sws_freeContext(is->img_convert_ctx);
2693 #endif
2694     av_free(is);
2695 }
2696
2697 static void stream_cycle_channel(VideoState *is, int codec_type)
2698 {
2699     AVFormatContext *ic = is->ic;
2700     int start_index, stream_index;
2701     AVStream *st;
2702
2703     if (codec_type == AVMEDIA_TYPE_VIDEO)
2704         start_index = is->video_stream;
2705     else if (codec_type == AVMEDIA_TYPE_AUDIO)
2706         start_index = is->audio_stream;
2707     else
2708         start_index = is->subtitle_stream;
2709     if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
2710         return;
2711     stream_index = start_index;
2712     for(;;) {
2713         if (++stream_index >= is->ic->nb_streams)
2714         {
2715             if (codec_type == AVMEDIA_TYPE_SUBTITLE)
2716             {
2717                 stream_index = -1;
2718                 goto the_end;
2719             } else
2720                 stream_index = 0;
2721         }
2722         if (stream_index == start_index)
2723             return;
2724         st = ic->streams[stream_index];
2725         if (st->codec->codec_type == codec_type) {
2726             /* check that parameters are OK */
2727             switch(codec_type) {
2728             case AVMEDIA_TYPE_AUDIO:
2729                 if (st->codec->sample_rate != 0 &&
2730                     st->codec->channels != 0)
2731                     goto the_end;
2732                 break;
2733             case AVMEDIA_TYPE_VIDEO:
2734             case AVMEDIA_TYPE_SUBTITLE:
2735                 goto the_end;
2736             default:
2737                 break;
2738             }
2739         }
2740     }
2741  the_end:
2742     stream_component_close(is, start_index);
2743     stream_component_open(is, stream_index);
2744 }
2745
2746
2747 static void toggle_full_screen(void)
2748 {
2749     is_full_screen = !is_full_screen;
2750     if (!fs_screen_width) {
2751         /* use default SDL method */
2752 //        SDL_WM_ToggleFullScreen(screen);
2753     }
2754     video_open(cur_stream);
2755 }
2756
2757 static void toggle_pause(void)
2758 {
2759     if (cur_stream)
2760         stream_pause(cur_stream);
2761     step = 0;
2762 }
2763
2764 static void step_to_next_frame(void)
2765 {
2766     if (cur_stream) {
2767         /* if the stream is paused unpause it, then step */
2768         if (cur_stream->paused)
2769             stream_pause(cur_stream);
2770     }
2771     step = 1;
2772 }
2773
2774 static void do_exit(void)
2775 {
2776     int i;
2777     if (cur_stream) {
2778         stream_close(cur_stream);
2779         cur_stream = NULL;
2780     }
2781     for (i = 0; i < AVMEDIA_TYPE_NB; i++)
2782         av_free(avcodec_opts[i]);
2783     av_free(avformat_opts);
2784     av_free(sws_opts);
2785 #if CONFIG_AVFILTER
2786     avfilter_uninit();
2787 #endif
2788     if (show_status)
2789         printf("\n");
2790     SDL_Quit();
2791     exit(0);
2792 }
2793
2794 static void toggle_audio_display(void)
2795 {
2796     if (cur_stream) {
2797         int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
2798         cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
2799         fill_rectangle(screen,
2800                     cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
2801                     bgcolor);
2802         SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
2803     }
2804 }
2805
2806 /* handle an event sent by the GUI */
2807 static void event_loop(void)
2808 {
2809     SDL_Event event;
2810     double incr, pos, frac;
2811
2812     for(;;) {
2813         double x;
2814         SDL_WaitEvent(&event);
2815         switch(event.type) {
2816         case SDL_KEYDOWN:
2817             switch(event.key.keysym.sym) {
2818             case SDLK_ESCAPE:
2819             case SDLK_q:
2820                 do_exit();
2821                 break;
2822             case SDLK_f:
2823                 toggle_full_screen();
2824                 break;
2825             case SDLK_p:
2826             case SDLK_SPACE:
2827                 toggle_pause();
2828                 break;
2829             case SDLK_s: //S: Step to next frame
2830                 step_to_next_frame();
2831                 break;
2832             case SDLK_a:
2833                 if (cur_stream)
2834                     stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
2835                 break;
2836             case SDLK_v:
2837                 if (cur_stream)
2838                     stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
2839                 break;
2840             case SDLK_t:
2841                 if (cur_stream)
2842                     stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
2843                 break;
2844             case SDLK_w:
2845                 toggle_audio_display();
2846                 break;
2847             case SDLK_LEFT:
2848                 incr = -10.0;
2849                 goto do_seek;
2850             case SDLK_RIGHT:
2851                 incr = 10.0;
2852                 goto do_seek;
2853             case SDLK_UP:
2854                 incr = 60.0;
2855                 goto do_seek;
2856             case SDLK_DOWN:
2857                 incr = -60.0;
2858             do_seek:
2859                 if (cur_stream) {
2860                     if (seek_by_bytes) {
2861                         if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
2862                             pos= cur_stream->video_current_pos;
2863                         }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
2864                             pos= cur_stream->audio_pkt.pos;
2865                         }else
2866                             pos = url_ftell(cur_stream->ic->pb);
2867                         if (cur_stream->ic->bit_rate)
2868                             incr *= cur_stream->ic->bit_rate / 8.0;
2869                         else
2870                             incr *= 180000.0;
2871                         pos += incr;
2872                         stream_seek(cur_stream, pos, incr, 1);
2873                     } else {
2874                         pos = get_master_clock(cur_stream);
2875                         pos += incr;
2876                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2877                     }
2878                 }
2879                 break;
2880             default:
2881                 break;
2882             }
2883             break;
2884         case SDL_MOUSEBUTTONDOWN:
2885         case SDL_MOUSEMOTION:
2886             if(event.type ==SDL_MOUSEBUTTONDOWN){
2887                 x= event.button.x;
2888             }else{
2889                 if(event.motion.state != SDL_PRESSED)
2890                     break;
2891                 x= event.motion.x;
2892             }
2893             if (cur_stream) {
2894                 if(seek_by_bytes || cur_stream->ic->duration<=0){
2895                     uint64_t size=  url_fsize(cur_stream->ic->pb);
2896                     stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
2897                 }else{
2898                     int64_t ts;
2899                     int ns, hh, mm, ss;
2900                     int tns, thh, tmm, tss;
2901                     tns = cur_stream->ic->duration/1000000LL;
2902                     thh = tns/3600;
2903                     tmm = (tns%3600)/60;
2904                     tss = (tns%60);
2905                     frac = x/cur_stream->width;
2906                     ns = frac*tns;
2907                     hh = ns/3600;
2908                     mm = (ns%3600)/60;
2909                     ss = (ns%60);
2910                     fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2911                             hh, mm, ss, thh, tmm, tss);
2912                     ts = frac*cur_stream->ic->duration;
2913                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2914                         ts += cur_stream->ic->start_time;
2915                     stream_seek(cur_stream, ts, 0, 0);
2916                 }
2917             }
2918             break;
2919         case SDL_VIDEORESIZE:
2920             if (cur_stream) {
2921                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2922                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2923                 screen_width = cur_stream->width = event.resize.w;
2924                 screen_height= cur_stream->height= event.resize.h;
2925             }
2926             break;
2927         case SDL_QUIT:
2928         case FF_QUIT_EVENT:
2929             do_exit();
2930             break;
2931         case FF_ALLOC_EVENT:
2932             video_open(event.user.data1);
2933             alloc_picture(event.user.data1);
2934             break;
2935         case FF_REFRESH_EVENT:
2936             video_refresh_timer(event.user.data1);
2937             cur_stream->refresh=0;
2938             break;
2939         default:
2940             break;
2941         }
2942     }
2943 }
2944
2945 static void opt_frame_size(const char *arg)
2946 {
2947     if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2948         fprintf(stderr, "Incorrect frame size\n");
2949         exit(1);
2950     }
2951     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2952         fprintf(stderr, "Frame size must be a multiple of 2\n");
2953         exit(1);
2954     }
2955 }
2956
2957 static int opt_width(const char *opt, const char *arg)
2958 {
2959     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2960     return 0;
2961 }
2962
2963 static int opt_height(const char *opt, const char *arg)
2964 {
2965     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2966     return 0;
2967 }
2968
2969 static void opt_format(const char *arg)
2970 {
2971     file_iformat = av_find_input_format(arg);
2972     if (!file_iformat) {
2973         fprintf(stderr, "Unknown input format: %s\n", arg);
2974         exit(1);
2975     }
2976 }
2977
2978 static void opt_frame_pix_fmt(const char *arg)
2979 {
2980     frame_pix_fmt = av_get_pix_fmt(arg);
2981 }
2982
2983 static int opt_sync(const char *opt, const char *arg)
2984 {
2985     if (!strcmp(arg, "audio"))
2986         av_sync_type = AV_SYNC_AUDIO_MASTER;
2987     else if (!strcmp(arg, "video"))
2988         av_sync_type = AV_SYNC_VIDEO_MASTER;
2989     else if (!strcmp(arg, "ext"))
2990         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2991     else {
2992         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2993         exit(1);
2994     }
2995     return 0;
2996 }
2997
2998 static int opt_seek(const char *opt, const char *arg)
2999 {
3000     start_time = parse_time_or_die(opt, arg, 1);
3001     return 0;
3002 }
3003
3004 static int opt_duration(const char *opt, const char *arg)
3005 {
3006     duration = parse_time_or_die(opt, arg, 1);
3007     return 0;
3008 }
3009
3010 static int opt_debug(const char *opt, const char *arg)
3011 {
3012     av_log_set_level(99);
3013     debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
3014     return 0;
3015 }
3016
3017 static int opt_vismv(const char *opt, const char *arg)
3018 {
3019     debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
3020     return 0;
3021 }
3022
3023 static int opt_thread_count(const char *opt, const char *arg)
3024 {
3025     thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
3026 #if !HAVE_THREADS
3027     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
3028 #endif
3029     return 0;
3030 }
3031
3032 static const OptionDef options[] = {
3033 #include "cmdutils_common_opts.h"
3034     { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
3035     { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
3036     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
3037     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
3038     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
3039     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
3040     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_AUDIO]}, "select desired audio stream", "stream_number" },
3041     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_VIDEO]}, "select desired video stream", "stream_number" },
3042     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" },
3043     { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
3044     { "t", HAS_ARG | OPT_FUNC2, {(void*)&opt_duration}, "play  \"duration\" seconds of audio/video", "duration" },
3045     { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" },
3046     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
3047     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
3048     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
3049     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
3050     { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
3051     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
3052     { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
3053     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
3054     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
3055     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3056     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
3057     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
3058     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
3059     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
3060     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
3061     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
3062     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
3063     { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
3064     { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
3065     { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" },
3066     { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&loop}, "set number of times the playback shall be looped", "loop count" },
3067     { "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" },
3068     { "window_title", OPT_STRING | HAS_ARG, {(void*)&window_title}, "set window title", "window title" },
3069 #if CONFIG_AVFILTER
3070     { "vf", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
3071 #endif
3072     { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" },
3073     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
3074     { NULL, },
3075 };
3076
3077 static void show_usage(void)
3078 {
3079     printf("Simple media player\n");
3080     printf("usage: ffplay [options] input_file\n");
3081     printf("\n");
3082 }
3083
3084 static void show_help(void)
3085 {
3086     show_usage();
3087     show_help_options(options, "Main options:\n",
3088                       OPT_EXPERT, 0);
3089     show_help_options(options, "\nAdvanced options:\n",
3090                       OPT_EXPERT, OPT_EXPERT);
3091     printf("\nWhile playing:\n"
3092            "q, ESC              quit\n"
3093            "f                   toggle full screen\n"
3094            "p, SPC              pause\n"
3095            "a                   cycle audio channel\n"
3096            "v                   cycle video channel\n"
3097            "t                   cycle subtitle channel\n"
3098            "w                   show audio waves\n"
3099            "s                   activate frame-step mode\n"
3100            "left/right          seek backward/forward 10 seconds\n"
3101            "down/up             seek backward/forward 1 minute\n"
3102            "mouse click         seek to percentage in file corresponding to fraction of width\n"
3103            );
3104 }
3105
3106 static void opt_input_file(const char *filename)
3107 {
3108     if (input_filename) {
3109         fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3110                 filename, input_filename);
3111         exit(1);
3112     }
3113     if (!strcmp(filename, "-"))
3114         filename = "pipe:";
3115     input_filename = filename;
3116 }
3117
3118 /* Called from the main */
3119 int main(int argc, char **argv)
3120 {
3121     int flags, i;
3122
3123     /* register all codecs, demux and protocols */
3124     avcodec_register_all();
3125 #if CONFIG_AVDEVICE
3126     avdevice_register_all();
3127 #endif
3128 #if CONFIG_AVFILTER
3129     avfilter_register_all();
3130 #endif
3131     av_register_all();
3132
3133     for(i=0; i<AVMEDIA_TYPE_NB; i++){
3134         avcodec_opts[i]= avcodec_alloc_context2(i);
3135     }
3136     avformat_opts = avformat_alloc_context();
3137 #if !CONFIG_AVFILTER
3138     sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
3139 #endif
3140
3141     show_banner();
3142
3143     parse_options(argc, argv, options, opt_input_file);
3144
3145     if (!input_filename) {
3146         show_usage();
3147         fprintf(stderr, "An input file must be specified\n");
3148         fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
3149         exit(1);
3150     }
3151
3152     if (display_disable) {
3153         video_disable = 1;
3154     }
3155     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3156 #if !defined(__MINGW32__) && !defined(__APPLE__)
3157     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3158 #endif
3159     if (SDL_Init (flags)) {
3160         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3161         exit(1);
3162     }
3163
3164     if (!display_disable) {
3165 #if HAVE_SDL_VIDEO_SIZE
3166         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3167         fs_screen_width = vi->current_w;
3168         fs_screen_height = vi->current_h;
3169 #endif
3170     }
3171
3172     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3173     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3174     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3175
3176     av_init_packet(&flush_pkt);
3177     flush_pkt.data= "FLUSH";
3178
3179     cur_stream = stream_open(input_filename, file_iformat);
3180
3181     event_loop();
3182
3183     /* never returns */
3184
3185     return 0;
3186 }