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