]> git.sesse.net Git - ffmpeg/blob - ffplay.c
Guess the duration before converting video and write guessed duration
[ffmpeg] / 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
231 /* current context */
232 static int is_full_screen;
233 static VideoState *cur_stream;
234 static int64_t audio_callback_time;
235
236 static AVPacket flush_pkt;
237
238 #define FF_ALLOC_EVENT   (SDL_USEREVENT)
239 #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
240 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
241
242 static SDL_Surface *screen;
243
244 static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
245
246 /* packet queue handling */
247 static void packet_queue_init(PacketQueue *q)
248 {
249     memset(q, 0, sizeof(PacketQueue));
250     q->mutex = SDL_CreateMutex();
251     q->cond = SDL_CreateCond();
252     packet_queue_put(q, &flush_pkt);
253 }
254
255 static void packet_queue_flush(PacketQueue *q)
256 {
257     AVPacketList *pkt, *pkt1;
258
259     SDL_LockMutex(q->mutex);
260     for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
261         pkt1 = pkt->next;
262         av_free_packet(&pkt->pkt);
263         av_freep(&pkt);
264     }
265     q->last_pkt = NULL;
266     q->first_pkt = NULL;
267     q->nb_packets = 0;
268     q->size = 0;
269     SDL_UnlockMutex(q->mutex);
270 }
271
272 static void packet_queue_end(PacketQueue *q)
273 {
274     packet_queue_flush(q);
275     SDL_DestroyMutex(q->mutex);
276     SDL_DestroyCond(q->cond);
277 }
278
279 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
280 {
281     AVPacketList *pkt1;
282
283     /* duplicate the packet */
284     if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
285         return -1;
286
287     pkt1 = av_malloc(sizeof(AVPacketList));
288     if (!pkt1)
289         return -1;
290     pkt1->pkt = *pkt;
291     pkt1->next = NULL;
292
293
294     SDL_LockMutex(q->mutex);
295
296     if (!q->last_pkt)
297
298         q->first_pkt = pkt1;
299     else
300         q->last_pkt->next = pkt1;
301     q->last_pkt = pkt1;
302     q->nb_packets++;
303     q->size += pkt1->pkt.size + sizeof(*pkt1);
304     /* XXX: should duplicate packet data in DV case */
305     SDL_CondSignal(q->cond);
306
307     SDL_UnlockMutex(q->mutex);
308     return 0;
309 }
310
311 static void packet_queue_abort(PacketQueue *q)
312 {
313     SDL_LockMutex(q->mutex);
314
315     q->abort_request = 1;
316
317     SDL_CondSignal(q->cond);
318
319     SDL_UnlockMutex(q->mutex);
320 }
321
322 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
323 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
324 {
325     AVPacketList *pkt1;
326     int ret;
327
328     SDL_LockMutex(q->mutex);
329
330     for(;;) {
331         if (q->abort_request) {
332             ret = -1;
333             break;
334         }
335
336         pkt1 = q->first_pkt;
337         if (pkt1) {
338             q->first_pkt = pkt1->next;
339             if (!q->first_pkt)
340                 q->last_pkt = NULL;
341             q->nb_packets--;
342             q->size -= pkt1->pkt.size + sizeof(*pkt1);
343             *pkt = pkt1->pkt;
344             av_free(pkt1);
345             ret = 1;
346             break;
347         } else if (!block) {
348             ret = 0;
349             break;
350         } else {
351             SDL_CondWait(q->cond, q->mutex);
352         }
353     }
354     SDL_UnlockMutex(q->mutex);
355     return ret;
356 }
357
358 static inline void fill_rectangle(SDL_Surface *screen,
359                                   int x, int y, int w, int h, int color)
360 {
361     SDL_Rect rect;
362     rect.x = x;
363     rect.y = y;
364     rect.w = w;
365     rect.h = h;
366     SDL_FillRect(screen, &rect, color);
367 }
368
369 #if 0
370 /* draw only the border of a rectangle */
371 void fill_border(VideoState *s, int x, int y, int w, int h, int color)
372 {
373     int w1, w2, h1, h2;
374
375     /* fill the background */
376     w1 = x;
377     if (w1 < 0)
378         w1 = 0;
379     w2 = s->width - (x + w);
380     if (w2 < 0)
381         w2 = 0;
382     h1 = y;
383     if (h1 < 0)
384         h1 = 0;
385     h2 = s->height - (y + h);
386     if (h2 < 0)
387         h2 = 0;
388     fill_rectangle(screen,
389                    s->xleft, s->ytop,
390                    w1, s->height,
391                    color);
392     fill_rectangle(screen,
393                    s->xleft + s->width - w2, s->ytop,
394                    w2, s->height,
395                    color);
396     fill_rectangle(screen,
397                    s->xleft + w1, s->ytop,
398                    s->width - w1 - w2, h1,
399                    color);
400     fill_rectangle(screen,
401                    s->xleft + w1, s->ytop + s->height - h2,
402                    s->width - w1 - w2, h2,
403                    color);
404 }
405 #endif
406
407 #define ALPHA_BLEND(a, oldp, newp, s)\
408 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
409
410 #define RGBA_IN(r, g, b, a, s)\
411 {\
412     unsigned int v = ((const uint32_t *)(s))[0];\
413     a = (v >> 24) & 0xff;\
414     r = (v >> 16) & 0xff;\
415     g = (v >> 8) & 0xff;\
416     b = v & 0xff;\
417 }
418
419 #define YUVA_IN(y, u, v, a, s, pal)\
420 {\
421     unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
422     a = (val >> 24) & 0xff;\
423     y = (val >> 16) & 0xff;\
424     u = (val >> 8) & 0xff;\
425     v = val & 0xff;\
426 }
427
428 #define YUVA_OUT(d, y, u, v, a)\
429 {\
430     ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
431 }
432
433
434 #define BPP 1
435
436 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
437 {
438     int wrap, wrap3, width2, skip2;
439     int y, u, v, a, u1, v1, a1, w, h;
440     uint8_t *lum, *cb, *cr;
441     const uint8_t *p;
442     const uint32_t *pal;
443     int dstx, dsty, dstw, dsth;
444
445     dstw = av_clip(rect->w, 0, imgw);
446     dsth = av_clip(rect->h, 0, imgh);
447     dstx = av_clip(rect->x, 0, imgw - dstw);
448     dsty = av_clip(rect->y, 0, imgh - dsth);
449     lum = dst->data[0] + dsty * dst->linesize[0];
450     cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
451     cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
452
453     width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
454     skip2 = dstx >> 1;
455     wrap = dst->linesize[0];
456     wrap3 = rect->pict.linesize[0];
457     p = rect->pict.data[0];
458     pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
459
460     if (dsty & 1) {
461         lum += dstx;
462         cb += skip2;
463         cr += skip2;
464
465         if (dstx & 1) {
466             YUVA_IN(y, u, v, a, p, pal);
467             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
468             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
469             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
470             cb++;
471             cr++;
472             lum++;
473             p += BPP;
474         }
475         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
476             YUVA_IN(y, u, v, a, p, pal);
477             u1 = u;
478             v1 = v;
479             a1 = a;
480             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
481
482             YUVA_IN(y, u, v, a, p + BPP, pal);
483             u1 += u;
484             v1 += v;
485             a1 += a;
486             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
487             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
488             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
489             cb++;
490             cr++;
491             p += 2 * BPP;
492             lum += 2;
493         }
494         if (w) {
495             YUVA_IN(y, u, v, a, p, pal);
496             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
497             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
498             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
499             p++;
500             lum++;
501         }
502         p += wrap3 - dstw * BPP;
503         lum += wrap - dstw - dstx;
504         cb += dst->linesize[1] - width2 - skip2;
505         cr += dst->linesize[2] - width2 - skip2;
506     }
507     for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
508         lum += dstx;
509         cb += skip2;
510         cr += skip2;
511
512         if (dstx & 1) {
513             YUVA_IN(y, u, v, a, p, pal);
514             u1 = u;
515             v1 = v;
516             a1 = a;
517             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
518             p += wrap3;
519             lum += wrap;
520             YUVA_IN(y, u, v, a, p, pal);
521             u1 += u;
522             v1 += v;
523             a1 += a;
524             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
525             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
526             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
527             cb++;
528             cr++;
529             p += -wrap3 + BPP;
530             lum += -wrap + 1;
531         }
532         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
533             YUVA_IN(y, u, v, a, p, pal);
534             u1 = u;
535             v1 = v;
536             a1 = a;
537             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
538
539             YUVA_IN(y, u, v, a, p + BPP, pal);
540             u1 += u;
541             v1 += v;
542             a1 += a;
543             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
544             p += wrap3;
545             lum += wrap;
546
547             YUVA_IN(y, u, v, a, p, pal);
548             u1 += u;
549             v1 += v;
550             a1 += a;
551             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
552
553             YUVA_IN(y, u, v, a, p + BPP, pal);
554             u1 += u;
555             v1 += v;
556             a1 += a;
557             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
558
559             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
560             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
561
562             cb++;
563             cr++;
564             p += -wrap3 + 2 * BPP;
565             lum += -wrap + 2;
566         }
567         if (w) {
568             YUVA_IN(y, u, v, a, p, pal);
569             u1 = u;
570             v1 = v;
571             a1 = a;
572             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
573             p += wrap3;
574             lum += wrap;
575             YUVA_IN(y, u, v, a, p, pal);
576             u1 += u;
577             v1 += v;
578             a1 += a;
579             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
580             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
581             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
582             cb++;
583             cr++;
584             p += -wrap3 + BPP;
585             lum += -wrap + 1;
586         }
587         p += wrap3 + (wrap3 - dstw * BPP);
588         lum += wrap + (wrap - dstw - dstx);
589         cb += dst->linesize[1] - width2 - skip2;
590         cr += dst->linesize[2] - width2 - skip2;
591     }
592     /* handle odd height */
593     if (h) {
594         lum += dstx;
595         cb += skip2;
596         cr += skip2;
597
598         if (dstx & 1) {
599             YUVA_IN(y, u, v, a, p, pal);
600             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
601             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
602             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
603             cb++;
604             cr++;
605             lum++;
606             p += BPP;
607         }
608         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
609             YUVA_IN(y, u, v, a, p, pal);
610             u1 = u;
611             v1 = v;
612             a1 = a;
613             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
614
615             YUVA_IN(y, u, v, a, p + BPP, pal);
616             u1 += u;
617             v1 += v;
618             a1 += a;
619             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
620             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
621             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
622             cb++;
623             cr++;
624             p += 2 * BPP;
625             lum += 2;
626         }
627         if (w) {
628             YUVA_IN(y, u, v, a, p, pal);
629             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
630             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
631             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
632         }
633     }
634 }
635
636 static void free_subpicture(SubPicture *sp)
637 {
638     int i;
639
640     for (i = 0; i < sp->sub.num_rects; i++)
641     {
642         av_freep(&sp->sub.rects[i]->pict.data[0]);
643         av_freep(&sp->sub.rects[i]->pict.data[1]);
644         av_freep(&sp->sub.rects[i]);
645     }
646
647     av_free(sp->sub.rects);
648
649     memset(&sp->sub, 0, sizeof(AVSubtitle));
650 }
651
652 static void video_image_display(VideoState *is)
653 {
654     VideoPicture *vp;
655     SubPicture *sp;
656     AVPicture pict;
657     float aspect_ratio;
658     int width, height, x, y;
659     SDL_Rect rect;
660     int i;
661
662     vp = &is->pictq[is->pictq_rindex];
663     if (vp->bmp) {
664         /* XXX: use variable in the frame */
665         if (is->video_st->sample_aspect_ratio.num)
666             aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
667         else if (is->video_st->codec->sample_aspect_ratio.num)
668             aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
669         else
670             aspect_ratio = 0;
671         if (aspect_ratio <= 0.0)
672             aspect_ratio = 1.0;
673         aspect_ratio *= (float)is->video_st->codec->width / is->video_st->codec->height;
674         /* if an active format is indicated, then it overrides the
675            mpeg format */
676 #if 0
677         if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
678             is->dtg_active_format = is->video_st->codec->dtg_active_format;
679             printf("dtg_active_format=%d\n", is->dtg_active_format);
680         }
681 #endif
682 #if 0
683         switch(is->video_st->codec->dtg_active_format) {
684         case FF_DTG_AFD_SAME:
685         default:
686             /* nothing to do */
687             break;
688         case FF_DTG_AFD_4_3:
689             aspect_ratio = 4.0 / 3.0;
690             break;
691         case FF_DTG_AFD_16_9:
692             aspect_ratio = 16.0 / 9.0;
693             break;
694         case FF_DTG_AFD_14_9:
695             aspect_ratio = 14.0 / 9.0;
696             break;
697         case FF_DTG_AFD_4_3_SP_14_9:
698             aspect_ratio = 14.0 / 9.0;
699             break;
700         case FF_DTG_AFD_16_9_SP_14_9:
701             aspect_ratio = 14.0 / 9.0;
702             break;
703         case FF_DTG_AFD_SP_4_3:
704             aspect_ratio = 4.0 / 3.0;
705             break;
706         }
707 #endif
708
709         if (is->subtitle_st)
710         {
711             if (is->subpq_size > 0)
712             {
713                 sp = &is->subpq[is->subpq_rindex];
714
715                 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
716                 {
717                     SDL_LockYUVOverlay (vp->bmp);
718
719                     pict.data[0] = vp->bmp->pixels[0];
720                     pict.data[1] = vp->bmp->pixels[2];
721                     pict.data[2] = vp->bmp->pixels[1];
722
723                     pict.linesize[0] = vp->bmp->pitches[0];
724                     pict.linesize[1] = vp->bmp->pitches[2];
725                     pict.linesize[2] = vp->bmp->pitches[1];
726
727                     for (i = 0; i < sp->sub.num_rects; i++)
728                         blend_subrect(&pict, sp->sub.rects[i],
729                                       vp->bmp->w, vp->bmp->h);
730
731                     SDL_UnlockYUVOverlay (vp->bmp);
732                 }
733             }
734         }
735
736
737         /* XXX: we suppose the screen has a 1.0 pixel ratio */
738         height = is->height;
739         width = ((int)rint(height * aspect_ratio)) & ~1;
740         if (width > is->width) {
741             width = is->width;
742             height = ((int)rint(width / aspect_ratio)) & ~1;
743         }
744         x = (is->width - width) / 2;
745         y = (is->height - height) / 2;
746         if (!is->no_background) {
747             /* fill the background */
748             //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
749         } else {
750             is->no_background = 0;
751         }
752         rect.x = is->xleft + x;
753         rect.y = is->ytop  + y;
754         rect.w = width;
755         rect.h = height;
756         SDL_DisplayYUVOverlay(vp->bmp, &rect);
757     } else {
758 #if 0
759         fill_rectangle(screen,
760                        is->xleft, is->ytop, is->width, is->height,
761                        QERGB(0x00, 0x00, 0x00));
762 #endif
763     }
764 }
765
766 static inline int compute_mod(int a, int b)
767 {
768     a = a % b;
769     if (a >= 0)
770         return a;
771     else
772         return a + b;
773 }
774
775 static void video_audio_display(VideoState *s)
776 {
777     int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
778     int ch, channels, h, h2, bgcolor, fgcolor;
779     int16_t time_diff;
780
781     /* compute display index : center on currently output samples */
782     channels = s->audio_st->codec->channels;
783     nb_display_channels = channels;
784     if (!s->paused) {
785         n = 2 * channels;
786         delay = audio_write_get_buf_size(s);
787         delay /= n;
788
789         /* to be more precise, we take into account the time spent since
790            the last buffer computation */
791         if (audio_callback_time) {
792             time_diff = av_gettime() - audio_callback_time;
793             delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
794         }
795
796         delay -= s->width / 2;
797         if (delay < s->width)
798             delay = s->width;
799
800         i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
801
802         h= INT_MIN;
803         for(i=0; i<1000; i+=channels){
804             int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
805             int a= s->sample_array[idx];
806             int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
807             int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
808             int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
809             int score= a-d;
810             if(h<score && (b^c)<0){
811                 h= score;
812                 i_start= idx;
813             }
814         }
815
816         s->last_i_start = i_start;
817     } else {
818         i_start = s->last_i_start;
819     }
820
821     bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
822     fill_rectangle(screen,
823                    s->xleft, s->ytop, s->width, s->height,
824                    bgcolor);
825
826     fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
827
828     /* total height for one channel */
829     h = s->height / nb_display_channels;
830     /* graph height / 2 */
831     h2 = (h * 9) / 20;
832     for(ch = 0;ch < nb_display_channels; ch++) {
833         i = i_start + ch;
834         y1 = s->ytop + ch * h + (h / 2); /* position of center line */
835         for(x = 0; x < s->width; x++) {
836             y = (s->sample_array[i] * h2) >> 15;
837             if (y < 0) {
838                 y = -y;
839                 ys = y1 - y;
840             } else {
841                 ys = y1;
842             }
843             fill_rectangle(screen,
844                            s->xleft + x, ys, 1, y,
845                            fgcolor);
846             i += channels;
847             if (i >= SAMPLE_ARRAY_SIZE)
848                 i -= SAMPLE_ARRAY_SIZE;
849         }
850     }
851
852     fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
853
854     for(ch = 1;ch < nb_display_channels; ch++) {
855         y = s->ytop + ch * h;
856         fill_rectangle(screen,
857                        s->xleft, y, s->width, 1,
858                        fgcolor);
859     }
860     SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
861 }
862
863 static int video_open(VideoState *is){
864     int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
865     int w,h;
866
867     if(is_full_screen) flags |= SDL_FULLSCREEN;
868     else               flags |= SDL_RESIZABLE;
869
870     if (is_full_screen && fs_screen_width) {
871         w = fs_screen_width;
872         h = fs_screen_height;
873     } else if(!is_full_screen && screen_width){
874         w = screen_width;
875         h = screen_height;
876     }else if (is->video_st && is->video_st->codec->width){
877         w = is->video_st->codec->width;
878         h = is->video_st->codec->height;
879     } else {
880         w = 640;
881         h = 480;
882     }
883 #ifndef __APPLE__
884     screen = SDL_SetVideoMode(w, h, 0, flags);
885 #else
886     /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
887     screen = SDL_SetVideoMode(w, h, 24, flags);
888 #endif
889     if (!screen) {
890         fprintf(stderr, "SDL: could not set video mode - exiting\n");
891         return -1;
892     }
893     SDL_WM_SetCaption("FFplay", "FFplay");
894
895     is->width = screen->w;
896     is->height = screen->h;
897
898     return 0;
899 }
900
901 /* display the current picture, if any */
902 static void video_display(VideoState *is)
903 {
904     if(!screen)
905         video_open(cur_stream);
906     if (is->audio_st && is->show_audio)
907         video_audio_display(is);
908     else if (is->video_st)
909         video_image_display(is);
910 }
911
912 static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
913 {
914     SDL_Event event;
915     event.type = FF_REFRESH_EVENT;
916     event.user.data1 = opaque;
917     SDL_PushEvent(&event);
918     return 0; /* 0 means stop timer */
919 }
920
921 /* schedule a video refresh in 'delay' ms */
922 static SDL_TimerID schedule_refresh(VideoState *is, int delay)
923 {
924     if(!delay) delay=1; //SDL seems to be buggy when the delay is 0
925     return SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
926 }
927
928 /* get the current audio clock value */
929 static double get_audio_clock(VideoState *is)
930 {
931     double pts;
932     int hw_buf_size, bytes_per_sec;
933     pts = is->audio_clock;
934     hw_buf_size = audio_write_get_buf_size(is);
935     bytes_per_sec = 0;
936     if (is->audio_st) {
937         bytes_per_sec = is->audio_st->codec->sample_rate *
938             2 * is->audio_st->codec->channels;
939     }
940     if (bytes_per_sec)
941         pts -= (double)hw_buf_size / bytes_per_sec;
942     return pts;
943 }
944
945 /* get the current video clock value */
946 static double get_video_clock(VideoState *is)
947 {
948     if (is->paused) {
949         return is->video_current_pts;
950     } else {
951         return is->video_current_pts_drift + av_gettime() / 1000000.0;
952     }
953 }
954
955 /* get the current external clock value */
956 static double get_external_clock(VideoState *is)
957 {
958     int64_t ti;
959     ti = av_gettime();
960     return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
961 }
962
963 /* get the current master clock value */
964 static double get_master_clock(VideoState *is)
965 {
966     double val;
967
968     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
969         if (is->video_st)
970             val = get_video_clock(is);
971         else
972             val = get_audio_clock(is);
973     } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
974         if (is->audio_st)
975             val = get_audio_clock(is);
976         else
977             val = get_video_clock(is);
978     } else {
979         val = get_external_clock(is);
980     }
981     return val;
982 }
983
984 /* seek in the stream */
985 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
986 {
987     if (!is->seek_req) {
988         is->seek_pos = pos;
989         is->seek_rel = rel;
990         is->seek_flags &= ~AVSEEK_FLAG_BYTE;
991         if (seek_by_bytes)
992             is->seek_flags |= AVSEEK_FLAG_BYTE;
993         is->seek_req = 1;
994     }
995 }
996
997 /* pause or resume the video */
998 static void stream_pause(VideoState *is)
999 {
1000     if (is->paused) {
1001         is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
1002         if(is->read_pause_return != AVERROR(ENOSYS)){
1003             is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1004         }
1005         is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1006     }
1007     is->paused = !is->paused;
1008 }
1009
1010 static double compute_frame_delay(double frame_current_pts, VideoState *is)
1011 {
1012     double actual_delay, delay, sync_threshold, ref_clock, diff;
1013
1014     /* compute nominal delay */
1015     delay = frame_current_pts - is->frame_last_pts;
1016     if (delay <= 0 || delay >= 10.0) {
1017         /* if incorrect delay, use previous one */
1018         delay = is->frame_last_delay;
1019     } else {
1020         is->frame_last_delay = delay;
1021     }
1022     is->frame_last_pts = frame_current_pts;
1023
1024     /* update delay to follow master synchronisation source */
1025     if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1026          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1027         /* if video is slave, we try to correct big delays by
1028            duplicating or deleting a frame */
1029         ref_clock = get_master_clock(is);
1030         diff = frame_current_pts - ref_clock;
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
1374             continue;
1375         }
1376
1377         /* NOTE: ipts is the PTS of the _first_ picture beginning in
1378            this packet, if any */
1379         is->video_st->codec->reordered_opaque= pkt->pts;
1380         len1 = avcodec_decode_video2(is->video_st->codec,
1381                                     frame, &got_picture,
1382                                     pkt);
1383
1384         if (got_picture) {
1385             if(pkt->dts != AV_NOPTS_VALUE){
1386                 is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1387                 is->last_dts_for_fault_detection= pkt->dts;
1388             }
1389             if(frame->reordered_opaque != AV_NOPTS_VALUE){
1390                 is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1391                 is->last_pts_for_fault_detection= frame->reordered_opaque;
1392             }
1393         }
1394
1395         if(   (   decoder_reorder_pts==1
1396                || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
1397                || pkt->dts == AV_NOPTS_VALUE)
1398            && frame->reordered_opaque != AV_NOPTS_VALUE)
1399             pts= frame->reordered_opaque;
1400         else if(pkt->dts != AV_NOPTS_VALUE)
1401             pts= pkt->dts;
1402         else
1403             pts= 0;
1404         pts *= av_q2d(is->video_st->time_base);
1405
1406 //            if (len1 < 0)
1407 //                break;
1408         if (got_picture) {
1409             if (output_picture2(is, frame, pts, pkt->pos) < 0)
1410                 goto the_end;
1411         }
1412         av_free_packet(pkt);
1413         if (step)
1414             if (cur_stream)
1415                 stream_pause(cur_stream);
1416     }
1417  the_end:
1418     av_free(frame);
1419     return 0;
1420 }
1421
1422 static int subtitle_thread(void *arg)
1423 {
1424     VideoState *is = arg;
1425     SubPicture *sp;
1426     AVPacket pkt1, *pkt = &pkt1;
1427     int len1, got_subtitle;
1428     double pts;
1429     int i, j;
1430     int r, g, b, y, u, v, a;
1431
1432     for(;;) {
1433         while (is->paused && !is->subtitleq.abort_request) {
1434             SDL_Delay(10);
1435         }
1436         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1437             break;
1438
1439         if(pkt->data == flush_pkt.data){
1440             avcodec_flush_buffers(is->subtitle_st->codec);
1441             continue;
1442         }
1443         SDL_LockMutex(is->subpq_mutex);
1444         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1445                !is->subtitleq.abort_request) {
1446             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1447         }
1448         SDL_UnlockMutex(is->subpq_mutex);
1449
1450         if (is->subtitleq.abort_request)
1451             goto the_end;
1452
1453         sp = &is->subpq[is->subpq_windex];
1454
1455        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1456            this packet, if any */
1457         pts = 0;
1458         if (pkt->pts != AV_NOPTS_VALUE)
1459             pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1460
1461         len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1462                                     &sp->sub, &got_subtitle,
1463                                     pkt);
1464 //            if (len1 < 0)
1465 //                break;
1466         if (got_subtitle && sp->sub.format == 0) {
1467             sp->pts = pts;
1468
1469             for (i = 0; i < sp->sub.num_rects; i++)
1470             {
1471                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1472                 {
1473                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1474                     y = RGB_TO_Y_CCIR(r, g, b);
1475                     u = RGB_TO_U_CCIR(r, g, b, 0);
1476                     v = RGB_TO_V_CCIR(r, g, b, 0);
1477                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1478                 }
1479             }
1480
1481             /* now we can update the picture count */
1482             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1483                 is->subpq_windex = 0;
1484             SDL_LockMutex(is->subpq_mutex);
1485             is->subpq_size++;
1486             SDL_UnlockMutex(is->subpq_mutex);
1487         }
1488         av_free_packet(pkt);
1489 //        if (step)
1490 //            if (cur_stream)
1491 //                stream_pause(cur_stream);
1492     }
1493  the_end:
1494     return 0;
1495 }
1496
1497 /* copy samples for viewing in editor window */
1498 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1499 {
1500     int size, len, channels;
1501
1502     channels = is->audio_st->codec->channels;
1503
1504     size = samples_size / sizeof(short);
1505     while (size > 0) {
1506         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1507         if (len > size)
1508             len = size;
1509         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1510         samples += len;
1511         is->sample_array_index += len;
1512         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1513             is->sample_array_index = 0;
1514         size -= len;
1515     }
1516 }
1517
1518 /* return the new audio buffer size (samples can be added or deleted
1519    to get better sync if video or external master clock) */
1520 static int synchronize_audio(VideoState *is, short *samples,
1521                              int samples_size1, double pts)
1522 {
1523     int n, samples_size;
1524     double ref_clock;
1525
1526     n = 2 * is->audio_st->codec->channels;
1527     samples_size = samples_size1;
1528
1529     /* if not master, then we try to remove or add samples to correct the clock */
1530     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1531          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1532         double diff, avg_diff;
1533         int wanted_size, min_size, max_size, nb_samples;
1534
1535         ref_clock = get_master_clock(is);
1536         diff = get_audio_clock(is) - ref_clock;
1537
1538         if (diff < AV_NOSYNC_THRESHOLD) {
1539             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1540             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1541                 /* not enough measures to have a correct estimate */
1542                 is->audio_diff_avg_count++;
1543             } else {
1544                 /* estimate the A-V difference */
1545                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1546
1547                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1548                     wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1549                     nb_samples = samples_size / n;
1550
1551                     min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1552                     max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1553                     if (wanted_size < min_size)
1554                         wanted_size = min_size;
1555                     else if (wanted_size > max_size)
1556                         wanted_size = max_size;
1557
1558                     /* add or remove samples to correction the synchro */
1559                     if (wanted_size < samples_size) {
1560                         /* remove samples */
1561                         samples_size = wanted_size;
1562                     } else if (wanted_size > samples_size) {
1563                         uint8_t *samples_end, *q;
1564                         int nb;
1565
1566                         /* add samples */
1567                         nb = (samples_size - wanted_size);
1568                         samples_end = (uint8_t *)samples + samples_size - n;
1569                         q = samples_end + n;
1570                         while (nb > 0) {
1571                             memcpy(q, samples_end, n);
1572                             q += n;
1573                             nb -= n;
1574                         }
1575                         samples_size = wanted_size;
1576                     }
1577                 }
1578 #if 0
1579                 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1580                        diff, avg_diff, samples_size - samples_size1,
1581                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
1582 #endif
1583             }
1584         } else {
1585             /* too big difference : may be initial PTS errors, so
1586                reset A-V filter */
1587             is->audio_diff_avg_count = 0;
1588             is->audio_diff_cum = 0;
1589         }
1590     }
1591
1592     return samples_size;
1593 }
1594
1595 /* decode one audio frame and returns its uncompressed size */
1596 static int audio_decode_frame(VideoState *is, double *pts_ptr)
1597 {
1598     AVPacket *pkt_temp = &is->audio_pkt_temp;
1599     AVPacket *pkt = &is->audio_pkt;
1600     AVCodecContext *dec= is->audio_st->codec;
1601     int n, len1, data_size;
1602     double pts;
1603
1604     for(;;) {
1605         /* NOTE: the audio packet can contain several frames */
1606         while (pkt_temp->size > 0) {
1607             data_size = sizeof(is->audio_buf1);
1608             len1 = avcodec_decode_audio3(dec,
1609                                         (int16_t *)is->audio_buf1, &data_size,
1610                                         pkt_temp);
1611             if (len1 < 0) {
1612                 /* if error, we skip the frame */
1613                 pkt_temp->size = 0;
1614                 break;
1615             }
1616
1617             pkt_temp->data += len1;
1618             pkt_temp->size -= len1;
1619             if (data_size <= 0)
1620                 continue;
1621
1622             if (dec->sample_fmt != is->audio_src_fmt) {
1623                 if (is->reformat_ctx)
1624                     av_audio_convert_free(is->reformat_ctx);
1625                 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1626                                                          dec->sample_fmt, 1, NULL, 0);
1627                 if (!is->reformat_ctx) {
1628                     fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1629                         avcodec_get_sample_fmt_name(dec->sample_fmt),
1630                         avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1631                         break;
1632                 }
1633                 is->audio_src_fmt= dec->sample_fmt;
1634             }
1635
1636             if (is->reformat_ctx) {
1637                 const void *ibuf[6]= {is->audio_buf1};
1638                 void *obuf[6]= {is->audio_buf2};
1639                 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1640                 int ostride[6]= {2};
1641                 int len= data_size/istride[0];
1642                 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1643                     printf("av_audio_convert() failed\n");
1644                     break;
1645                 }
1646                 is->audio_buf= is->audio_buf2;
1647                 /* FIXME: existing code assume that data_size equals framesize*channels*2
1648                           remove this legacy cruft */
1649                 data_size= len*2;
1650             }else{
1651                 is->audio_buf= is->audio_buf1;
1652             }
1653
1654             /* if no pts, then compute it */
1655             pts = is->audio_clock;
1656             *pts_ptr = pts;
1657             n = 2 * dec->channels;
1658             is->audio_clock += (double)data_size /
1659                 (double)(n * dec->sample_rate);
1660 #if defined(DEBUG_SYNC)
1661             {
1662                 static double last_clock;
1663                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1664                        is->audio_clock - last_clock,
1665                        is->audio_clock, pts);
1666                 last_clock = is->audio_clock;
1667             }
1668 #endif
1669             return data_size;
1670         }
1671
1672         /* free the current packet */
1673         if (pkt->data)
1674             av_free_packet(pkt);
1675
1676         if (is->paused || is->audioq.abort_request) {
1677             return -1;
1678         }
1679
1680         /* read next packet */
1681         if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1682             return -1;
1683         if(pkt->data == flush_pkt.data){
1684             avcodec_flush_buffers(dec);
1685             continue;
1686         }
1687
1688         pkt_temp->data = pkt->data;
1689         pkt_temp->size = pkt->size;
1690
1691         /* if update the audio clock with the pts */
1692         if (pkt->pts != AV_NOPTS_VALUE) {
1693             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1694         }
1695     }
1696 }
1697
1698 /* get the current audio output buffer size, in samples. With SDL, we
1699    cannot have a precise information */
1700 static int audio_write_get_buf_size(VideoState *is)
1701 {
1702     return is->audio_buf_size - is->audio_buf_index;
1703 }
1704
1705
1706 /* prepare a new audio buffer */
1707 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1708 {
1709     VideoState *is = opaque;
1710     int audio_size, len1;
1711     double pts;
1712
1713     audio_callback_time = av_gettime();
1714
1715     while (len > 0) {
1716         if (is->audio_buf_index >= is->audio_buf_size) {
1717            audio_size = audio_decode_frame(is, &pts);
1718            if (audio_size < 0) {
1719                 /* if error, just output silence */
1720                is->audio_buf = is->audio_buf1;
1721                is->audio_buf_size = 1024;
1722                memset(is->audio_buf, 0, is->audio_buf_size);
1723            } else {
1724                if (is->show_audio)
1725                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1726                audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1727                                               pts);
1728                is->audio_buf_size = audio_size;
1729            }
1730            is->audio_buf_index = 0;
1731         }
1732         len1 = is->audio_buf_size - is->audio_buf_index;
1733         if (len1 > len)
1734             len1 = len;
1735         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1736         len -= len1;
1737         stream += len1;
1738         is->audio_buf_index += len1;
1739     }
1740 }
1741
1742 /* open a given stream. Return 0 if OK */
1743 static int stream_component_open(VideoState *is, int stream_index)
1744 {
1745     AVFormatContext *ic = is->ic;
1746     AVCodecContext *enc;
1747     AVCodec *codec;
1748     SDL_AudioSpec wanted_spec, spec;
1749
1750     if (stream_index < 0 || stream_index >= ic->nb_streams)
1751         return -1;
1752     enc = ic->streams[stream_index]->codec;
1753
1754     /* prepare audio output */
1755     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1756         if (enc->channels > 0) {
1757             enc->request_channels = FFMIN(2, enc->channels);
1758         } else {
1759             enc->request_channels = 2;
1760         }
1761     }
1762
1763     codec = avcodec_find_decoder(enc->codec_id);
1764     enc->debug_mv = debug_mv;
1765     enc->debug = debug;
1766     enc->workaround_bugs = workaround_bugs;
1767     enc->lowres = lowres;
1768     if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1769     enc->idct_algo= idct;
1770     if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1771     enc->skip_frame= skip_frame;
1772     enc->skip_idct= skip_idct;
1773     enc->skip_loop_filter= skip_loop_filter;
1774     enc->error_recognition= error_recognition;
1775     enc->error_concealment= error_concealment;
1776     avcodec_thread_init(enc, thread_count);
1777
1778     set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1779
1780     if (!codec ||
1781         avcodec_open(enc, codec) < 0)
1782         return -1;
1783
1784     /* prepare audio output */
1785     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1786         wanted_spec.freq = enc->sample_rate;
1787         wanted_spec.format = AUDIO_S16SYS;
1788         wanted_spec.channels = enc->channels;
1789         wanted_spec.silence = 0;
1790         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1791         wanted_spec.callback = sdl_audio_callback;
1792         wanted_spec.userdata = is;
1793         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1794             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1795             return -1;
1796         }
1797         is->audio_hw_buf_size = spec.size;
1798         is->audio_src_fmt= SAMPLE_FMT_S16;
1799     }
1800
1801     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1802     switch(enc->codec_type) {
1803     case CODEC_TYPE_AUDIO:
1804         is->audio_stream = stream_index;
1805         is->audio_st = ic->streams[stream_index];
1806         is->audio_buf_size = 0;
1807         is->audio_buf_index = 0;
1808
1809         /* init averaging filter */
1810         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1811         is->audio_diff_avg_count = 0;
1812         /* since we do not have a precise anough audio fifo fullness,
1813            we correct audio sync only if larger than this threshold */
1814         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1815
1816         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1817         packet_queue_init(&is->audioq);
1818         SDL_PauseAudio(0);
1819         break;
1820     case CODEC_TYPE_VIDEO:
1821         is->video_stream = stream_index;
1822         is->video_st = ic->streams[stream_index];
1823
1824         is->frame_timer = (double)av_gettime() / 1000000.0;
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         if (!display_disable)
2026             is->show_audio = 1;
2027     }
2028
2029     if (subtitle_index >= 0) {
2030         stream_component_open(is, subtitle_index);
2031     }
2032
2033     if (is->video_stream < 0 && is->audio_stream < 0) {
2034         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2035         ret = -1;
2036         goto fail;
2037     }
2038
2039     for(;;) {
2040         if (is->abort_request)
2041             break;
2042         if (is->paused != is->last_paused) {
2043             is->last_paused = is->paused;
2044             if (is->paused)
2045                 is->read_pause_return= av_read_pause(ic);
2046             else
2047                 av_read_play(ic);
2048         }
2049 #if CONFIG_RTSP_DEMUXER
2050         if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2051             /* wait 10 ms to avoid trying to get another packet */
2052             /* XXX: horrible */
2053             SDL_Delay(10);
2054             continue;
2055         }
2056 #endif
2057         if (is->seek_req) {
2058             int64_t seek_target= is->seek_pos;
2059             int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2060             int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2061 //FIXME the +-2 is due to rounding being not done in the correct direction in generation
2062 //      of the seek_pos/seek_rel variables
2063
2064             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2065             if (ret < 0) {
2066                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2067             }else{
2068                 if (is->audio_stream >= 0) {
2069                     packet_queue_flush(&is->audioq);
2070                     packet_queue_put(&is->audioq, &flush_pkt);
2071                 }
2072                 if (is->subtitle_stream >= 0) {
2073                     packet_queue_flush(&is->subtitleq);
2074                     packet_queue_put(&is->subtitleq, &flush_pkt);
2075                 }
2076                 if (is->video_stream >= 0) {
2077                     packet_queue_flush(&is->videoq);
2078                     packet_queue_put(&is->videoq, &flush_pkt);
2079                 }
2080             }
2081             is->seek_req = 0;
2082             eof= 0;
2083         }
2084
2085         /* if the queue are full, no need to read more */
2086         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2087             || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2088                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2089                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2090             /* wait 10 ms */
2091             SDL_Delay(10);
2092             continue;
2093         }
2094         if(url_feof(ic->pb) || eof) {
2095             if(is->video_stream >= 0){
2096                 av_init_packet(pkt);
2097                 pkt->data=NULL;
2098                 pkt->size=0;
2099                 pkt->stream_index= is->video_stream;
2100                 packet_queue_put(&is->videoq, pkt);
2101             }
2102             SDL_Delay(10);
2103             continue;
2104         }
2105         ret = av_read_frame(ic, pkt);
2106         if (ret < 0) {
2107             if (ret == AVERROR_EOF)
2108                 eof=1;
2109             if (url_ferror(ic->pb))
2110                 break;
2111             SDL_Delay(100); /* wait for user event */
2112             continue;
2113         }
2114         if (pkt->stream_index == is->audio_stream) {
2115             packet_queue_put(&is->audioq, pkt);
2116         } else if (pkt->stream_index == is->video_stream) {
2117             packet_queue_put(&is->videoq, pkt);
2118         } else if (pkt->stream_index == is->subtitle_stream) {
2119             packet_queue_put(&is->subtitleq, pkt);
2120         } else {
2121             av_free_packet(pkt);
2122         }
2123     }
2124     /* wait until the end */
2125     while (!is->abort_request) {
2126         SDL_Delay(100);
2127     }
2128
2129     ret = 0;
2130  fail:
2131     /* disable interrupting */
2132     global_video_state = NULL;
2133
2134     /* close each stream */
2135     if (is->audio_stream >= 0)
2136         stream_component_close(is, is->audio_stream);
2137     if (is->video_stream >= 0)
2138         stream_component_close(is, is->video_stream);
2139     if (is->subtitle_stream >= 0)
2140         stream_component_close(is, is->subtitle_stream);
2141     if (is->ic) {
2142         av_close_input_file(is->ic);
2143         is->ic = NULL; /* safety */
2144     }
2145     url_set_interrupt_cb(NULL);
2146
2147     if (ret != 0) {
2148         SDL_Event event;
2149
2150         event.type = FF_QUIT_EVENT;
2151         event.user.data1 = is;
2152         SDL_PushEvent(&event);
2153     }
2154     return 0;
2155 }
2156
2157 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2158 {
2159     VideoState *is;
2160
2161     is = av_mallocz(sizeof(VideoState));
2162     if (!is)
2163         return NULL;
2164     av_strlcpy(is->filename, filename, sizeof(is->filename));
2165     is->iformat = iformat;
2166     is->ytop = 0;
2167     is->xleft = 0;
2168
2169     /* start video display */
2170     is->pictq_mutex = SDL_CreateMutex();
2171     is->pictq_cond = SDL_CreateCond();
2172
2173     is->subpq_mutex = SDL_CreateMutex();
2174     is->subpq_cond = SDL_CreateCond();
2175
2176     /* add the refresh timer to draw the picture */
2177     schedule_refresh(is, 40);
2178
2179     is->av_sync_type = av_sync_type;
2180     is->parse_tid = SDL_CreateThread(decode_thread, is);
2181     if (!is->parse_tid) {
2182         av_free(is);
2183         return NULL;
2184     }
2185     return is;
2186 }
2187
2188 static void stream_close(VideoState *is)
2189 {
2190     VideoPicture *vp;
2191     int i;
2192     /* XXX: use a special url_shutdown call to abort parse cleanly */
2193     is->abort_request = 1;
2194     SDL_WaitThread(is->parse_tid, NULL);
2195
2196     /* free all pictures */
2197     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2198         vp = &is->pictq[i];
2199         if (vp->bmp) {
2200             SDL_FreeYUVOverlay(vp->bmp);
2201             vp->bmp = NULL;
2202         }
2203     }
2204     SDL_DestroyMutex(is->pictq_mutex);
2205     SDL_DestroyCond(is->pictq_cond);
2206     SDL_DestroyMutex(is->subpq_mutex);
2207     SDL_DestroyCond(is->subpq_cond);
2208     if (is->img_convert_ctx)
2209         sws_freeContext(is->img_convert_ctx);
2210     av_free(is);
2211 }
2212
2213 static void stream_cycle_channel(VideoState *is, int codec_type)
2214 {
2215     AVFormatContext *ic = is->ic;
2216     int start_index, stream_index;
2217     AVStream *st;
2218
2219     if (codec_type == CODEC_TYPE_VIDEO)
2220         start_index = is->video_stream;
2221     else if (codec_type == CODEC_TYPE_AUDIO)
2222         start_index = is->audio_stream;
2223     else
2224         start_index = is->subtitle_stream;
2225     if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2226         return;
2227     stream_index = start_index;
2228     for(;;) {
2229         if (++stream_index >= is->ic->nb_streams)
2230         {
2231             if (codec_type == CODEC_TYPE_SUBTITLE)
2232             {
2233                 stream_index = -1;
2234                 goto the_end;
2235             } else
2236                 stream_index = 0;
2237         }
2238         if (stream_index == start_index)
2239             return;
2240         st = ic->streams[stream_index];
2241         if (st->codec->codec_type == codec_type) {
2242             /* check that parameters are OK */
2243             switch(codec_type) {
2244             case CODEC_TYPE_AUDIO:
2245                 if (st->codec->sample_rate != 0 &&
2246                     st->codec->channels != 0)
2247                     goto the_end;
2248                 break;
2249             case CODEC_TYPE_VIDEO:
2250             case CODEC_TYPE_SUBTITLE:
2251                 goto the_end;
2252             default:
2253                 break;
2254             }
2255         }
2256     }
2257  the_end:
2258     stream_component_close(is, start_index);
2259     stream_component_open(is, stream_index);
2260 }
2261
2262
2263 static void toggle_full_screen(void)
2264 {
2265     is_full_screen = !is_full_screen;
2266     if (!fs_screen_width) {
2267         /* use default SDL method */
2268 //        SDL_WM_ToggleFullScreen(screen);
2269     }
2270     video_open(cur_stream);
2271 }
2272
2273 static void toggle_pause(void)
2274 {
2275     if (cur_stream)
2276         stream_pause(cur_stream);
2277     step = 0;
2278 }
2279
2280 static void step_to_next_frame(void)
2281 {
2282     if (cur_stream) {
2283         /* if the stream is paused unpause it, then step */
2284         if (cur_stream->paused)
2285             stream_pause(cur_stream);
2286     }
2287     step = 1;
2288 }
2289
2290 static void do_exit(void)
2291 {
2292     int i;
2293     if (cur_stream) {
2294         stream_close(cur_stream);
2295         cur_stream = NULL;
2296     }
2297     for (i = 0; i < CODEC_TYPE_NB; i++)
2298         av_free(avcodec_opts[i]);
2299     av_free(avformat_opts);
2300     av_free(sws_opts);
2301     if (show_status)
2302         printf("\n");
2303     SDL_Quit();
2304     exit(0);
2305 }
2306
2307 static void toggle_audio_display(void)
2308 {
2309     if (cur_stream) {
2310         cur_stream->show_audio = !cur_stream->show_audio;
2311     }
2312 }
2313
2314 /* handle an event sent by the GUI */
2315 static void event_loop(void)
2316 {
2317     SDL_Event event;
2318     double incr, pos, frac;
2319
2320     for(;;) {
2321         SDL_WaitEvent(&event);
2322         switch(event.type) {
2323         case SDL_KEYDOWN:
2324             switch(event.key.keysym.sym) {
2325             case SDLK_ESCAPE:
2326             case SDLK_q:
2327                 do_exit();
2328                 break;
2329             case SDLK_f:
2330                 toggle_full_screen();
2331                 break;
2332             case SDLK_p:
2333             case SDLK_SPACE:
2334                 toggle_pause();
2335                 break;
2336             case SDLK_s: //S: Step to next frame
2337                 step_to_next_frame();
2338                 break;
2339             case SDLK_a:
2340                 if (cur_stream)
2341                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2342                 break;
2343             case SDLK_v:
2344                 if (cur_stream)
2345                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2346                 break;
2347             case SDLK_t:
2348                 if (cur_stream)
2349                     stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2350                 break;
2351             case SDLK_w:
2352                 toggle_audio_display();
2353                 break;
2354             case SDLK_LEFT:
2355                 incr = -10.0;
2356                 goto do_seek;
2357             case SDLK_RIGHT:
2358                 incr = 10.0;
2359                 goto do_seek;
2360             case SDLK_UP:
2361                 incr = 60.0;
2362                 goto do_seek;
2363             case SDLK_DOWN:
2364                 incr = -60.0;
2365             do_seek:
2366                 if (cur_stream) {
2367                     if (seek_by_bytes) {
2368                         if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
2369                             pos= cur_stream->video_current_pos;
2370                         }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
2371                             pos= cur_stream->audio_pkt.pos;
2372                         }else
2373                             pos = url_ftell(cur_stream->ic->pb);
2374                         if (cur_stream->ic->bit_rate)
2375                             incr *= cur_stream->ic->bit_rate / 60.0;
2376                         else
2377                             incr *= 180000.0;
2378                         pos += incr;
2379                         stream_seek(cur_stream, pos, incr, 1);
2380                     } else {
2381                         pos = get_master_clock(cur_stream);
2382                         pos += incr;
2383                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2384                     }
2385                 }
2386                 break;
2387             default:
2388                 break;
2389             }
2390             break;
2391         case SDL_MOUSEBUTTONDOWN:
2392             if (cur_stream) {
2393                 if(seek_by_bytes || cur_stream->ic->duration<=0){
2394                     uint64_t size=  url_fsize(cur_stream->ic->pb);
2395                     stream_seek(cur_stream, size*(double)event.button.x/(double)cur_stream->width, 0, 1);
2396                 }else{
2397                     int64_t ts;
2398                     int ns, hh, mm, ss;
2399                     int tns, thh, tmm, tss;
2400                     tns = cur_stream->ic->duration/1000000LL;
2401                     thh = tns/3600;
2402                     tmm = (tns%3600)/60;
2403                     tss = (tns%60);
2404                     frac = (double)event.button.x/(double)cur_stream->width;
2405                     ns = frac*tns;
2406                     hh = ns/3600;
2407                     mm = (ns%3600)/60;
2408                     ss = (ns%60);
2409                     fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2410                             hh, mm, ss, thh, tmm, tss);
2411                     ts = frac*cur_stream->ic->duration;
2412                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2413                         ts += cur_stream->ic->start_time;
2414                     stream_seek(cur_stream, ts, 0, 0);
2415                 }
2416             }
2417             break;
2418         case SDL_VIDEORESIZE:
2419             if (cur_stream) {
2420                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2421                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2422                 screen_width = cur_stream->width = event.resize.w;
2423                 screen_height= cur_stream->height= event.resize.h;
2424             }
2425             break;
2426         case SDL_QUIT:
2427         case FF_QUIT_EVENT:
2428             do_exit();
2429             break;
2430         case FF_ALLOC_EVENT:
2431             video_open(event.user.data1);
2432             alloc_picture(event.user.data1);
2433             break;
2434         case FF_REFRESH_EVENT:
2435             video_refresh_timer(event.user.data1);
2436             break;
2437         default:
2438             break;
2439         }
2440     }
2441 }
2442
2443 static void opt_frame_size(const char *arg)
2444 {
2445     if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2446         fprintf(stderr, "Incorrect frame size\n");
2447         exit(1);
2448     }
2449     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2450         fprintf(stderr, "Frame size must be a multiple of 2\n");
2451         exit(1);
2452     }
2453 }
2454
2455 static int opt_width(const char *opt, const char *arg)
2456 {
2457     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2458     return 0;
2459 }
2460
2461 static int opt_height(const char *opt, const char *arg)
2462 {
2463     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2464     return 0;
2465 }
2466
2467 static void opt_format(const char *arg)
2468 {
2469     file_iformat = av_find_input_format(arg);
2470     if (!file_iformat) {
2471         fprintf(stderr, "Unknown input format: %s\n", arg);
2472         exit(1);
2473     }
2474 }
2475
2476 static void opt_frame_pix_fmt(const char *arg)
2477 {
2478     frame_pix_fmt = av_get_pix_fmt(arg);
2479 }
2480
2481 static int opt_sync(const char *opt, const char *arg)
2482 {
2483     if (!strcmp(arg, "audio"))
2484         av_sync_type = AV_SYNC_AUDIO_MASTER;
2485     else if (!strcmp(arg, "video"))
2486         av_sync_type = AV_SYNC_VIDEO_MASTER;
2487     else if (!strcmp(arg, "ext"))
2488         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2489     else {
2490         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2491         exit(1);
2492     }
2493     return 0;
2494 }
2495
2496 static int opt_seek(const char *opt, const char *arg)
2497 {
2498     start_time = parse_time_or_die(opt, arg, 1);
2499     return 0;
2500 }
2501
2502 static int opt_debug(const char *opt, const char *arg)
2503 {
2504     av_log_set_level(99);
2505     debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2506     return 0;
2507 }
2508
2509 static int opt_vismv(const char *opt, const char *arg)
2510 {
2511     debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2512     return 0;
2513 }
2514
2515 static int opt_thread_count(const char *opt, const char *arg)
2516 {
2517     thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2518 #if !HAVE_THREADS
2519     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2520 #endif
2521     return 0;
2522 }
2523
2524 static const OptionDef options[] = {
2525 #include "cmdutils_common_opts.h"
2526     { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2527     { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2528     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2529     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2530     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2531     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2532     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2533     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2534     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
2535     { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2536     { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto" },
2537     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2538     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2539     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2540     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2541     { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2542     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2543     { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2544     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2545     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2546     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2547     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2548     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2549     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2550     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2551     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2552     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2553     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2554     { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2555     { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2556     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2557     { NULL, },
2558 };
2559
2560 static void show_usage(void)
2561 {
2562     printf("Simple media player\n");
2563     printf("usage: ffplay [options] input_file\n");
2564     printf("\n");
2565 }
2566
2567 static void show_help(void)
2568 {
2569     show_usage();
2570     show_help_options(options, "Main options:\n",
2571                       OPT_EXPERT, 0);
2572     show_help_options(options, "\nAdvanced options:\n",
2573                       OPT_EXPERT, OPT_EXPERT);
2574     printf("\nWhile playing:\n"
2575            "q, ESC              quit\n"
2576            "f                   toggle full screen\n"
2577            "p, SPC              pause\n"
2578            "a                   cycle audio channel\n"
2579            "v                   cycle video channel\n"
2580            "t                   cycle subtitle channel\n"
2581            "w                   show audio waves\n"
2582            "left/right          seek backward/forward 10 seconds\n"
2583            "down/up             seek backward/forward 1 minute\n"
2584            "mouse click         seek to percentage in file corresponding to fraction of width\n"
2585            );
2586 }
2587
2588 static void opt_input_file(const char *filename)
2589 {
2590     if (!strcmp(filename, "-"))
2591         filename = "pipe:";
2592     input_filename = filename;
2593 }
2594
2595 /* Called from the main */
2596 int main(int argc, char **argv)
2597 {
2598     int flags, i;
2599
2600     /* register all codecs, demux and protocols */
2601     avcodec_register_all();
2602     avdevice_register_all();
2603     av_register_all();
2604
2605     for(i=0; i<CODEC_TYPE_NB; i++){
2606         avcodec_opts[i]= avcodec_alloc_context2(i);
2607     }
2608     avformat_opts = avformat_alloc_context();
2609     sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2610
2611     show_banner();
2612
2613     parse_options(argc, argv, options, opt_input_file);
2614
2615     if (!input_filename) {
2616         show_usage();
2617         fprintf(stderr, "An input file must be specified\n");
2618         fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2619         exit(1);
2620     }
2621
2622     if (display_disable) {
2623         video_disable = 1;
2624     }
2625     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2626 #if !defined(__MINGW32__) && !defined(__APPLE__)
2627     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2628 #endif
2629     if (SDL_Init (flags)) {
2630         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2631         exit(1);
2632     }
2633
2634     if (!display_disable) {
2635 #if HAVE_SDL_VIDEO_SIZE
2636         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2637         fs_screen_width = vi->current_w;
2638         fs_screen_height = vi->current_h;
2639 #endif
2640     }
2641
2642     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2643     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2644     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2645     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2646
2647     av_init_packet(&flush_pkt);
2648     flush_pkt.data= "FLUSH";
2649
2650     cur_stream = stream_open(input_filename, file_iformat);
2651
2652     event_loop();
2653
2654     /* never returns */
2655
2656     return 0;
2657 }