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