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