]> git.sesse.net Git - ffmpeg/blob - ffplay.c
7aa742d9094dd07bf10fdfc4d1b04e2aaf005758
[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         diff = get_video_clock(is) - get_master_clock(is);
1030
1031         /* skip or repeat frame. We take into account the
1032            delay to compute the threshold. I still don't know
1033            if it is the best guess */
1034         sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1035         if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1036             if (diff <= -sync_threshold)
1037                 delay = 0;
1038             else if (diff >= sync_threshold)
1039                 delay = 2 * delay;
1040         }
1041     }
1042
1043     is->frame_timer += delay;
1044     /* compute the REAL delay (we need to do that to avoid
1045        long term errors */
1046     actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1047     if (actual_delay < 0.010) {
1048         /* XXX: should skip picture */
1049         actual_delay = 0.010;
1050     }
1051
1052 #if defined(DEBUG_SYNC)
1053     printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1054             delay, actual_delay, frame_current_pts, -diff);
1055 #endif
1056
1057     return actual_delay;
1058 }
1059
1060 /* called to display each frame */
1061 static void video_refresh_timer(void *opaque)
1062 {
1063     VideoState *is = opaque;
1064     VideoPicture *vp;
1065
1066     SubPicture *sp, *sp2;
1067
1068     if (is->video_st) {
1069         if (is->pictq_size == 0) {
1070             fprintf(stderr, "Internal error detected in the SDL timer\n");
1071         } else {
1072             /* dequeue the picture */
1073             vp = &is->pictq[is->pictq_rindex];
1074
1075             /* update current video pts */
1076             is->video_current_pts = vp->pts;
1077             is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1078             is->video_current_pos = vp->pos;
1079
1080             if(is->subtitle_st) {
1081                 if (is->subtitle_stream_changed) {
1082                     SDL_LockMutex(is->subpq_mutex);
1083
1084                     while (is->subpq_size) {
1085                         free_subpicture(&is->subpq[is->subpq_rindex]);
1086
1087                         /* update queue size and signal for next picture */
1088                         if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1089                             is->subpq_rindex = 0;
1090
1091                         is->subpq_size--;
1092                     }
1093                     is->subtitle_stream_changed = 0;
1094
1095                     SDL_CondSignal(is->subpq_cond);
1096                     SDL_UnlockMutex(is->subpq_mutex);
1097                 } else {
1098                     if (is->subpq_size > 0) {
1099                         sp = &is->subpq[is->subpq_rindex];
1100
1101                         if (is->subpq_size > 1)
1102                             sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1103                         else
1104                             sp2 = NULL;
1105
1106                         if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1107                                 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1108                         {
1109                             free_subpicture(sp);
1110
1111                             /* update queue size and signal for next picture */
1112                             if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1113                                 is->subpq_rindex = 0;
1114
1115                             SDL_LockMutex(is->subpq_mutex);
1116                             is->subpq_size--;
1117                             SDL_CondSignal(is->subpq_cond);
1118                             SDL_UnlockMutex(is->subpq_mutex);
1119                         }
1120                     }
1121                 }
1122             }
1123
1124             /* display picture */
1125             video_display(is);
1126
1127             /* update queue size and signal for next picture */
1128             if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1129                 is->pictq_rindex = 0;
1130
1131             SDL_LockMutex(is->pictq_mutex);
1132             vp->timer_id= 0;
1133             is->pictq_size--;
1134             SDL_CondSignal(is->pictq_cond);
1135             SDL_UnlockMutex(is->pictq_mutex);
1136         }
1137     } else if (is->audio_st) {
1138         /* draw the next audio frame */
1139
1140         schedule_refresh(is, 40);
1141
1142         /* if only audio stream, then display the audio bars (better
1143            than nothing, just to test the implementation */
1144
1145         /* display picture */
1146         video_display(is);
1147     } else {
1148         schedule_refresh(is, 100);
1149     }
1150     if (show_status) {
1151         static int64_t last_time;
1152         int64_t cur_time;
1153         int aqsize, vqsize, sqsize;
1154         double av_diff;
1155
1156         cur_time = av_gettime();
1157         if (!last_time || (cur_time - last_time) >= 30000) {
1158             aqsize = 0;
1159             vqsize = 0;
1160             sqsize = 0;
1161             if (is->audio_st)
1162                 aqsize = is->audioq.size;
1163             if (is->video_st)
1164                 vqsize = is->videoq.size;
1165             if (is->subtitle_st)
1166                 sqsize = is->subtitleq.size;
1167             av_diff = 0;
1168             if (is->audio_st && is->video_st)
1169                 av_diff = get_audio_clock(is) - get_video_clock(is);
1170             printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB f=%Ld/%Ld   \r",
1171                    get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts);
1172             fflush(stdout);
1173             last_time = cur_time;
1174         }
1175     }
1176 }
1177
1178 /* allocate a picture (needs to do that in main thread to avoid
1179    potential locking problems */
1180 static void alloc_picture(void *opaque)
1181 {
1182     VideoState *is = opaque;
1183     VideoPicture *vp;
1184
1185     vp = &is->pictq[is->pictq_windex];
1186
1187     if (vp->bmp)
1188         SDL_FreeYUVOverlay(vp->bmp);
1189
1190     vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1191                                    is->video_st->codec->height,
1192                                    SDL_YV12_OVERLAY,
1193                                    screen);
1194     vp->width = is->video_st->codec->width;
1195     vp->height = is->video_st->codec->height;
1196
1197     SDL_LockMutex(is->pictq_mutex);
1198     vp->allocated = 1;
1199     SDL_CondSignal(is->pictq_cond);
1200     SDL_UnlockMutex(is->pictq_mutex);
1201 }
1202
1203 /**
1204  *
1205  * @param pts the dts of the pkt / pts of the frame and guessed if not known
1206  */
1207 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
1208 {
1209     VideoPicture *vp;
1210     int dst_pix_fmt;
1211
1212     /* wait until we have space to put a new picture */
1213     SDL_LockMutex(is->pictq_mutex);
1214     while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1215            !is->videoq.abort_request) {
1216         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1217     }
1218     SDL_UnlockMutex(is->pictq_mutex);
1219
1220     if (is->videoq.abort_request)
1221         return -1;
1222
1223     vp = &is->pictq[is->pictq_windex];
1224
1225     /* alloc or resize hardware picture buffer */
1226     if (!vp->bmp ||
1227         vp->width != is->video_st->codec->width ||
1228         vp->height != is->video_st->codec->height) {
1229         SDL_Event event;
1230
1231         vp->allocated = 0;
1232
1233         /* the allocation must be done in the main thread to avoid
1234            locking problems */
1235         event.type = FF_ALLOC_EVENT;
1236         event.user.data1 = is;
1237         SDL_PushEvent(&event);
1238
1239         /* wait until the picture is allocated */
1240         SDL_LockMutex(is->pictq_mutex);
1241         while (!vp->allocated && !is->videoq.abort_request) {
1242             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1243         }
1244         SDL_UnlockMutex(is->pictq_mutex);
1245
1246         if (is->videoq.abort_request)
1247             return -1;
1248     }
1249
1250     /* if the frame is not skipped, then display it */
1251     if (vp->bmp) {
1252         AVPicture pict;
1253
1254         /* get a pointer on the bitmap */
1255         SDL_LockYUVOverlay (vp->bmp);
1256
1257         dst_pix_fmt = PIX_FMT_YUV420P;
1258         memset(&pict,0,sizeof(AVPicture));
1259         pict.data[0] = vp->bmp->pixels[0];
1260         pict.data[1] = vp->bmp->pixels[2];
1261         pict.data[2] = vp->bmp->pixels[1];
1262
1263         pict.linesize[0] = vp->bmp->pitches[0];
1264         pict.linesize[1] = vp->bmp->pitches[2];
1265         pict.linesize[2] = vp->bmp->pitches[1];
1266         sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1267         is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1268             is->video_st->codec->width, is->video_st->codec->height,
1269             is->video_st->codec->pix_fmt,
1270             is->video_st->codec->width, is->video_st->codec->height,
1271             dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1272         if (is->img_convert_ctx == NULL) {
1273             fprintf(stderr, "Cannot initialize the conversion context\n");
1274             exit(1);
1275         }
1276         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1277                   0, is->video_st->codec->height, pict.data, pict.linesize);
1278         /* update the bitmap content */
1279         SDL_UnlockYUVOverlay(vp->bmp);
1280
1281         vp->pts = pts;
1282         vp->pos = pos;
1283
1284         /* now we can update the picture count */
1285         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1286             is->pictq_windex = 0;
1287         SDL_LockMutex(is->pictq_mutex);
1288         is->pictq_size++;
1289         //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
1290         vp->timer_id= schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1291         SDL_UnlockMutex(is->pictq_mutex);
1292     }
1293     return 0;
1294 }
1295
1296 /**
1297  * compute the exact PTS for the picture if it is omitted in the stream
1298  * @param pts1 the dts of the pkt / pts of the frame
1299  */
1300 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1301 {
1302     double frame_delay, pts;
1303
1304     pts = pts1;
1305
1306     if (pts != 0) {
1307         /* update video clock with pts, if present */
1308         is->video_clock = pts;
1309     } else {
1310         pts = is->video_clock;
1311     }
1312     /* update video clock for next frame */
1313     frame_delay = av_q2d(is->video_st->codec->time_base);
1314     /* for MPEG2, the frame can be repeated, so we update the
1315        clock accordingly */
1316     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1317     is->video_clock += frame_delay;
1318
1319 #if defined(DEBUG_SYNC) && 0
1320     {
1321         int ftype;
1322         if (src_frame->pict_type == FF_B_TYPE)
1323             ftype = 'B';
1324         else if (src_frame->pict_type == FF_I_TYPE)
1325             ftype = 'I';
1326         else
1327             ftype = 'P';
1328         printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1329                ftype, pts, pts1);
1330     }
1331 #endif
1332     return queue_picture(is, src_frame, pts, pos);
1333 }
1334
1335 static int video_thread(void *arg)
1336 {
1337     VideoState *is = arg;
1338     AVPacket pkt1, *pkt = &pkt1;
1339     int len1, got_picture, i;
1340     AVFrame *frame= avcodec_alloc_frame();
1341     double pts;
1342
1343     for(;;) {
1344         while (is->paused && !is->videoq.abort_request) {
1345             SDL_Delay(10);
1346         }
1347         if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1348             break;
1349
1350         if(pkt->data == flush_pkt.data){
1351             avcodec_flush_buffers(is->video_st->codec);
1352
1353             SDL_LockMutex(is->pictq_mutex);
1354             //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1355             for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){
1356                 if(is->pictq[i].timer_id){
1357                     SDL_RemoveTimer(is->pictq[i].timer_id);
1358                     is->pictq[i].timer_id=0;
1359                     schedule_refresh(is, 1);
1360                 }
1361             }
1362             while (is->pictq_size && !is->videoq.abort_request) {
1363                 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1364             }
1365             is->video_current_pos= -1;
1366             SDL_UnlockMutex(is->pictq_mutex);
1367
1368             is->last_dts_for_fault_detection=
1369             is->last_pts_for_fault_detection= INT64_MIN;
1370             is->frame_last_pts= AV_NOPTS_VALUE;
1371             is->frame_last_delay = 0;
1372
1373             continue;
1374         }
1375
1376         /* NOTE: ipts is the PTS of the _first_ picture beginning in
1377            this packet, if any */
1378         is->video_st->codec->reordered_opaque= pkt->pts;
1379         len1 = avcodec_decode_video2(is->video_st->codec,
1380                                     frame, &got_picture,
1381                                     pkt);
1382
1383         if (got_picture) {
1384             if(pkt->dts != AV_NOPTS_VALUE){
1385                 is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1386                 is->last_dts_for_fault_detection= pkt->dts;
1387             }
1388             if(frame->reordered_opaque != AV_NOPTS_VALUE){
1389                 is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1390                 is->last_pts_for_fault_detection= frame->reordered_opaque;
1391             }
1392         }
1393
1394         if(   (   decoder_reorder_pts==1
1395                || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
1396                || pkt->dts == AV_NOPTS_VALUE)
1397            && frame->reordered_opaque != AV_NOPTS_VALUE)
1398             pts= frame->reordered_opaque;
1399         else if(pkt->dts != AV_NOPTS_VALUE)
1400             pts= pkt->dts;
1401         else
1402             pts= 0;
1403         pts *= av_q2d(is->video_st->time_base);
1404
1405 //            if (len1 < 0)
1406 //                break;
1407         if (got_picture) {
1408             if (output_picture2(is, frame, pts, pkt->pos) < 0)
1409                 goto the_end;
1410         }
1411         av_free_packet(pkt);
1412         if (step)
1413             if (cur_stream)
1414                 stream_pause(cur_stream);
1415     }
1416  the_end:
1417     av_free(frame);
1418     return 0;
1419 }
1420
1421 static int subtitle_thread(void *arg)
1422 {
1423     VideoState *is = arg;
1424     SubPicture *sp;
1425     AVPacket pkt1, *pkt = &pkt1;
1426     int len1, got_subtitle;
1427     double pts;
1428     int i, j;
1429     int r, g, b, y, u, v, a;
1430
1431     for(;;) {
1432         while (is->paused && !is->subtitleq.abort_request) {
1433             SDL_Delay(10);
1434         }
1435         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1436             break;
1437
1438         if(pkt->data == flush_pkt.data){
1439             avcodec_flush_buffers(is->subtitle_st->codec);
1440             continue;
1441         }
1442         SDL_LockMutex(is->subpq_mutex);
1443         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1444                !is->subtitleq.abort_request) {
1445             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1446         }
1447         SDL_UnlockMutex(is->subpq_mutex);
1448
1449         if (is->subtitleq.abort_request)
1450             goto the_end;
1451
1452         sp = &is->subpq[is->subpq_windex];
1453
1454        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1455            this packet, if any */
1456         pts = 0;
1457         if (pkt->pts != AV_NOPTS_VALUE)
1458             pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1459
1460         len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1461                                     &sp->sub, &got_subtitle,
1462                                     pkt);
1463 //            if (len1 < 0)
1464 //                break;
1465         if (got_subtitle && sp->sub.format == 0) {
1466             sp->pts = pts;
1467
1468             for (i = 0; i < sp->sub.num_rects; i++)
1469             {
1470                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1471                 {
1472                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1473                     y = RGB_TO_Y_CCIR(r, g, b);
1474                     u = RGB_TO_U_CCIR(r, g, b, 0);
1475                     v = RGB_TO_V_CCIR(r, g, b, 0);
1476                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1477                 }
1478             }
1479
1480             /* now we can update the picture count */
1481             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1482                 is->subpq_windex = 0;
1483             SDL_LockMutex(is->subpq_mutex);
1484             is->subpq_size++;
1485             SDL_UnlockMutex(is->subpq_mutex);
1486         }
1487         av_free_packet(pkt);
1488 //        if (step)
1489 //            if (cur_stream)
1490 //                stream_pause(cur_stream);
1491     }
1492  the_end:
1493     return 0;
1494 }
1495
1496 /* copy samples for viewing in editor window */
1497 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1498 {
1499     int size, len, channels;
1500
1501     channels = is->audio_st->codec->channels;
1502
1503     size = samples_size / sizeof(short);
1504     while (size > 0) {
1505         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1506         if (len > size)
1507             len = size;
1508         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1509         samples += len;
1510         is->sample_array_index += len;
1511         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1512             is->sample_array_index = 0;
1513         size -= len;
1514     }
1515 }
1516
1517 /* return the new audio buffer size (samples can be added or deleted
1518    to get better sync if video or external master clock) */
1519 static int synchronize_audio(VideoState *is, short *samples,
1520                              int samples_size1, double pts)
1521 {
1522     int n, samples_size;
1523     double ref_clock;
1524
1525     n = 2 * is->audio_st->codec->channels;
1526     samples_size = samples_size1;
1527
1528     /* if not master, then we try to remove or add samples to correct the clock */
1529     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1530          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1531         double diff, avg_diff;
1532         int wanted_size, min_size, max_size, nb_samples;
1533
1534         ref_clock = get_master_clock(is);
1535         diff = get_audio_clock(is) - ref_clock;
1536
1537         if (diff < AV_NOSYNC_THRESHOLD) {
1538             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1539             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1540                 /* not enough measures to have a correct estimate */
1541                 is->audio_diff_avg_count++;
1542             } else {
1543                 /* estimate the A-V difference */
1544                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1545
1546                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1547                     wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1548                     nb_samples = samples_size / n;
1549
1550                     min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1551                     max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1552                     if (wanted_size < min_size)
1553                         wanted_size = min_size;
1554                     else if (wanted_size > max_size)
1555                         wanted_size = max_size;
1556
1557                     /* add or remove samples to correction the synchro */
1558                     if (wanted_size < samples_size) {
1559                         /* remove samples */
1560                         samples_size = wanted_size;
1561                     } else if (wanted_size > samples_size) {
1562                         uint8_t *samples_end, *q;
1563                         int nb;
1564
1565                         /* add samples */
1566                         nb = (samples_size - wanted_size);
1567                         samples_end = (uint8_t *)samples + samples_size - n;
1568                         q = samples_end + n;
1569                         while (nb > 0) {
1570                             memcpy(q, samples_end, n);
1571                             q += n;
1572                             nb -= n;
1573                         }
1574                         samples_size = wanted_size;
1575                     }
1576                 }
1577 #if 0
1578                 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1579                        diff, avg_diff, samples_size - samples_size1,
1580                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
1581 #endif
1582             }
1583         } else {
1584             /* too big difference : may be initial PTS errors, so
1585                reset A-V filter */
1586             is->audio_diff_avg_count = 0;
1587             is->audio_diff_cum = 0;
1588         }
1589     }
1590
1591     return samples_size;
1592 }
1593
1594 /* decode one audio frame and returns its uncompressed size */
1595 static int audio_decode_frame(VideoState *is, double *pts_ptr)
1596 {
1597     AVPacket *pkt_temp = &is->audio_pkt_temp;
1598     AVPacket *pkt = &is->audio_pkt;
1599     AVCodecContext *dec= is->audio_st->codec;
1600     int n, len1, data_size;
1601     double pts;
1602
1603     for(;;) {
1604         /* NOTE: the audio packet can contain several frames */
1605         while (pkt_temp->size > 0) {
1606             data_size = sizeof(is->audio_buf1);
1607             len1 = avcodec_decode_audio3(dec,
1608                                         (int16_t *)is->audio_buf1, &data_size,
1609                                         pkt_temp);
1610             if (len1 < 0) {
1611                 /* if error, we skip the frame */
1612                 pkt_temp->size = 0;
1613                 break;
1614             }
1615
1616             pkt_temp->data += len1;
1617             pkt_temp->size -= len1;
1618             if (data_size <= 0)
1619                 continue;
1620
1621             if (dec->sample_fmt != is->audio_src_fmt) {
1622                 if (is->reformat_ctx)
1623                     av_audio_convert_free(is->reformat_ctx);
1624                 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1625                                                          dec->sample_fmt, 1, NULL, 0);
1626                 if (!is->reformat_ctx) {
1627                     fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1628                         avcodec_get_sample_fmt_name(dec->sample_fmt),
1629                         avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1630                         break;
1631                 }
1632                 is->audio_src_fmt= dec->sample_fmt;
1633             }
1634
1635             if (is->reformat_ctx) {
1636                 const void *ibuf[6]= {is->audio_buf1};
1637                 void *obuf[6]= {is->audio_buf2};
1638                 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1639                 int ostride[6]= {2};
1640                 int len= data_size/istride[0];
1641                 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1642                     printf("av_audio_convert() failed\n");
1643                     break;
1644                 }
1645                 is->audio_buf= is->audio_buf2;
1646                 /* FIXME: existing code assume that data_size equals framesize*channels*2
1647                           remove this legacy cruft */
1648                 data_size= len*2;
1649             }else{
1650                 is->audio_buf= is->audio_buf1;
1651             }
1652
1653             /* if no pts, then compute it */
1654             pts = is->audio_clock;
1655             *pts_ptr = pts;
1656             n = 2 * dec->channels;
1657             is->audio_clock += (double)data_size /
1658                 (double)(n * dec->sample_rate);
1659 #if defined(DEBUG_SYNC)
1660             {
1661                 static double last_clock;
1662                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1663                        is->audio_clock - last_clock,
1664                        is->audio_clock, pts);
1665                 last_clock = is->audio_clock;
1666             }
1667 #endif
1668             return data_size;
1669         }
1670
1671         /* free the current packet */
1672         if (pkt->data)
1673             av_free_packet(pkt);
1674
1675         if (is->paused || is->audioq.abort_request) {
1676             return -1;
1677         }
1678
1679         /* read next packet */
1680         if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1681             return -1;
1682         if(pkt->data == flush_pkt.data){
1683             avcodec_flush_buffers(dec);
1684             continue;
1685         }
1686
1687         pkt_temp->data = pkt->data;
1688         pkt_temp->size = pkt->size;
1689
1690         /* if update the audio clock with the pts */
1691         if (pkt->pts != AV_NOPTS_VALUE) {
1692             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1693         }
1694     }
1695 }
1696
1697 /* get the current audio output buffer size, in samples. With SDL, we
1698    cannot have a precise information */
1699 static int audio_write_get_buf_size(VideoState *is)
1700 {
1701     return is->audio_buf_size - is->audio_buf_index;
1702 }
1703
1704
1705 /* prepare a new audio buffer */
1706 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1707 {
1708     VideoState *is = opaque;
1709     int audio_size, len1;
1710     double pts;
1711
1712     audio_callback_time = av_gettime();
1713
1714     while (len > 0) {
1715         if (is->audio_buf_index >= is->audio_buf_size) {
1716            audio_size = audio_decode_frame(is, &pts);
1717            if (audio_size < 0) {
1718                 /* if error, just output silence */
1719                is->audio_buf = is->audio_buf1;
1720                is->audio_buf_size = 1024;
1721                memset(is->audio_buf, 0, is->audio_buf_size);
1722            } else {
1723                if (is->show_audio)
1724                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1725                audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1726                                               pts);
1727                is->audio_buf_size = audio_size;
1728            }
1729            is->audio_buf_index = 0;
1730         }
1731         len1 = is->audio_buf_size - is->audio_buf_index;
1732         if (len1 > len)
1733             len1 = len;
1734         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1735         len -= len1;
1736         stream += len1;
1737         is->audio_buf_index += len1;
1738     }
1739 }
1740
1741 /* open a given stream. Return 0 if OK */
1742 static int stream_component_open(VideoState *is, int stream_index)
1743 {
1744     AVFormatContext *ic = is->ic;
1745     AVCodecContext *enc;
1746     AVCodec *codec;
1747     SDL_AudioSpec wanted_spec, spec;
1748
1749     if (stream_index < 0 || stream_index >= ic->nb_streams)
1750         return -1;
1751     enc = ic->streams[stream_index]->codec;
1752
1753     /* prepare audio output */
1754     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1755         if (enc->channels > 0) {
1756             enc->request_channels = FFMIN(2, enc->channels);
1757         } else {
1758             enc->request_channels = 2;
1759         }
1760     }
1761
1762     codec = avcodec_find_decoder(enc->codec_id);
1763     enc->debug_mv = debug_mv;
1764     enc->debug = debug;
1765     enc->workaround_bugs = workaround_bugs;
1766     enc->lowres = lowres;
1767     if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1768     enc->idct_algo= idct;
1769     if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1770     enc->skip_frame= skip_frame;
1771     enc->skip_idct= skip_idct;
1772     enc->skip_loop_filter= skip_loop_filter;
1773     enc->error_recognition= error_recognition;
1774     enc->error_concealment= error_concealment;
1775     avcodec_thread_init(enc, thread_count);
1776
1777     set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1778
1779     if (!codec ||
1780         avcodec_open(enc, codec) < 0)
1781         return -1;
1782
1783     /* prepare audio output */
1784     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1785         wanted_spec.freq = enc->sample_rate;
1786         wanted_spec.format = AUDIO_S16SYS;
1787         wanted_spec.channels = enc->channels;
1788         wanted_spec.silence = 0;
1789         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1790         wanted_spec.callback = sdl_audio_callback;
1791         wanted_spec.userdata = is;
1792         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1793             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1794             return -1;
1795         }
1796         is->audio_hw_buf_size = spec.size;
1797         is->audio_src_fmt= SAMPLE_FMT_S16;
1798     }
1799
1800     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1801     switch(enc->codec_type) {
1802     case CODEC_TYPE_AUDIO:
1803         is->audio_stream = stream_index;
1804         is->audio_st = ic->streams[stream_index];
1805         is->audio_buf_size = 0;
1806         is->audio_buf_index = 0;
1807
1808         /* init averaging filter */
1809         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1810         is->audio_diff_avg_count = 0;
1811         /* since we do not have a precise anough audio fifo fullness,
1812            we correct audio sync only if larger than this threshold */
1813         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1814
1815         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1816         packet_queue_init(&is->audioq);
1817         SDL_PauseAudio(0);
1818         break;
1819     case CODEC_TYPE_VIDEO:
1820         is->video_stream = stream_index;
1821         is->video_st = ic->streams[stream_index];
1822
1823         is->frame_timer = (double)av_gettime() / 1000000.0;
1824 //        is->video_current_pts_time = av_gettime();
1825
1826         packet_queue_init(&is->videoq);
1827         is->video_tid = SDL_CreateThread(video_thread, is);
1828         break;
1829     case CODEC_TYPE_SUBTITLE:
1830         is->subtitle_stream = stream_index;
1831         is->subtitle_st = ic->streams[stream_index];
1832         packet_queue_init(&is->subtitleq);
1833
1834         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1835         break;
1836     default:
1837         break;
1838     }
1839     return 0;
1840 }
1841
1842 static void stream_component_close(VideoState *is, int stream_index)
1843 {
1844     AVFormatContext *ic = is->ic;
1845     AVCodecContext *enc;
1846
1847     if (stream_index < 0 || stream_index >= ic->nb_streams)
1848         return;
1849     enc = ic->streams[stream_index]->codec;
1850
1851     switch(enc->codec_type) {
1852     case CODEC_TYPE_AUDIO:
1853         packet_queue_abort(&is->audioq);
1854
1855         SDL_CloseAudio();
1856
1857         packet_queue_end(&is->audioq);
1858         if (is->reformat_ctx)
1859             av_audio_convert_free(is->reformat_ctx);
1860         break;
1861     case CODEC_TYPE_VIDEO:
1862         packet_queue_abort(&is->videoq);
1863
1864         /* note: we also signal this mutex to make sure we deblock the
1865            video thread in all cases */
1866         SDL_LockMutex(is->pictq_mutex);
1867         SDL_CondSignal(is->pictq_cond);
1868         SDL_UnlockMutex(is->pictq_mutex);
1869
1870         SDL_WaitThread(is->video_tid, NULL);
1871
1872         packet_queue_end(&is->videoq);
1873         break;
1874     case CODEC_TYPE_SUBTITLE:
1875         packet_queue_abort(&is->subtitleq);
1876
1877         /* note: we also signal this mutex to make sure we deblock the
1878            video thread in all cases */
1879         SDL_LockMutex(is->subpq_mutex);
1880         is->subtitle_stream_changed = 1;
1881
1882         SDL_CondSignal(is->subpq_cond);
1883         SDL_UnlockMutex(is->subpq_mutex);
1884
1885         SDL_WaitThread(is->subtitle_tid, NULL);
1886
1887         packet_queue_end(&is->subtitleq);
1888         break;
1889     default:
1890         break;
1891     }
1892
1893     ic->streams[stream_index]->discard = AVDISCARD_ALL;
1894     avcodec_close(enc);
1895     switch(enc->codec_type) {
1896     case CODEC_TYPE_AUDIO:
1897         is->audio_st = NULL;
1898         is->audio_stream = -1;
1899         break;
1900     case CODEC_TYPE_VIDEO:
1901         is->video_st = NULL;
1902         is->video_stream = -1;
1903         break;
1904     case CODEC_TYPE_SUBTITLE:
1905         is->subtitle_st = NULL;
1906         is->subtitle_stream = -1;
1907         break;
1908     default:
1909         break;
1910     }
1911 }
1912
1913 /* since we have only one decoding thread, we can use a global
1914    variable instead of a thread local variable */
1915 static VideoState *global_video_state;
1916
1917 static int decode_interrupt_cb(void)
1918 {
1919     return (global_video_state && global_video_state->abort_request);
1920 }
1921
1922 /* this thread gets the stream from the disk or the network */
1923 static int decode_thread(void *arg)
1924 {
1925     VideoState *is = arg;
1926     AVFormatContext *ic;
1927     int err, i, ret, video_index, audio_index, subtitle_index;
1928     AVPacket pkt1, *pkt = &pkt1;
1929     AVFormatParameters params, *ap = &params;
1930     int eof=0;
1931
1932     ic = avformat_alloc_context();
1933
1934     video_index = -1;
1935     audio_index = -1;
1936     subtitle_index = -1;
1937     is->video_stream = -1;
1938     is->audio_stream = -1;
1939     is->subtitle_stream = -1;
1940
1941     global_video_state = is;
1942     url_set_interrupt_cb(decode_interrupt_cb);
1943
1944     memset(ap, 0, sizeof(*ap));
1945
1946     ap->prealloced_context = 1;
1947     ap->width = frame_width;
1948     ap->height= frame_height;
1949     ap->time_base= (AVRational){1, 25};
1950     ap->pix_fmt = frame_pix_fmt;
1951
1952     set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
1953
1954     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1955     if (err < 0) {
1956         print_error(is->filename, err);
1957         ret = -1;
1958         goto fail;
1959     }
1960     is->ic = ic;
1961
1962     if(genpts)
1963         ic->flags |= AVFMT_FLAG_GENPTS;
1964
1965     err = av_find_stream_info(ic);
1966     if (err < 0) {
1967         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1968         ret = -1;
1969         goto fail;
1970     }
1971     if(ic->pb)
1972         ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1973
1974     if(seek_by_bytes<0)
1975         seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
1976
1977     /* if seeking requested, we execute it */
1978     if (start_time != AV_NOPTS_VALUE) {
1979         int64_t timestamp;
1980
1981         timestamp = start_time;
1982         /* add the stream start time */
1983         if (ic->start_time != AV_NOPTS_VALUE)
1984             timestamp += ic->start_time;
1985         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
1986         if (ret < 0) {
1987             fprintf(stderr, "%s: could not seek to position %0.3f\n",
1988                     is->filename, (double)timestamp / AV_TIME_BASE);
1989         }
1990     }
1991
1992     for(i = 0; i < ic->nb_streams; i++) {
1993         AVCodecContext *enc = ic->streams[i]->codec;
1994         ic->streams[i]->discard = AVDISCARD_ALL;
1995         switch(enc->codec_type) {
1996         case CODEC_TYPE_AUDIO:
1997             if (wanted_audio_stream-- >= 0 && !audio_disable)
1998                 audio_index = i;
1999             break;
2000         case CODEC_TYPE_VIDEO:
2001             if (wanted_video_stream-- >= 0 && !video_disable)
2002                 video_index = i;
2003             break;
2004         case CODEC_TYPE_SUBTITLE:
2005             if (wanted_subtitle_stream-- >= 0 && !video_disable)
2006                 subtitle_index = i;
2007             break;
2008         default:
2009             break;
2010         }
2011     }
2012     if (show_status) {
2013         dump_format(ic, 0, is->filename, 0);
2014     }
2015
2016     /* open the streams */
2017     if (audio_index >= 0) {
2018         stream_component_open(is, audio_index);
2019     }
2020
2021     if (video_index >= 0) {
2022         stream_component_open(is, video_index);
2023     } else {
2024         /* add the refresh timer to draw the picture */
2025         schedule_refresh(is, 40);
2026
2027         if (!display_disable)
2028             is->show_audio = 1;
2029     }
2030
2031     if (subtitle_index >= 0) {
2032         stream_component_open(is, subtitle_index);
2033     }
2034
2035     if (is->video_stream < 0 && is->audio_stream < 0) {
2036         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2037         ret = -1;
2038         goto fail;
2039     }
2040
2041     for(;;) {
2042         if (is->abort_request)
2043             break;
2044         if (is->paused != is->last_paused) {
2045             is->last_paused = is->paused;
2046             if (is->paused)
2047                 is->read_pause_return= av_read_pause(ic);
2048             else
2049                 av_read_play(ic);
2050         }
2051 #if CONFIG_RTSP_DEMUXER
2052         if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2053             /* wait 10 ms to avoid trying to get another packet */
2054             /* XXX: horrible */
2055             SDL_Delay(10);
2056             continue;
2057         }
2058 #endif
2059         if (is->seek_req) {
2060             int64_t seek_target= is->seek_pos;
2061             int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2062             int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2063 //FIXME the +-2 is due to rounding being not done in the correct direction in generation
2064 //      of the seek_pos/seek_rel variables
2065
2066             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2067             if (ret < 0) {
2068                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2069             }else{
2070                 if (is->audio_stream >= 0) {
2071                     packet_queue_flush(&is->audioq);
2072                     packet_queue_put(&is->audioq, &flush_pkt);
2073                 }
2074                 if (is->subtitle_stream >= 0) {
2075                     packet_queue_flush(&is->subtitleq);
2076                     packet_queue_put(&is->subtitleq, &flush_pkt);
2077                 }
2078                 if (is->video_stream >= 0) {
2079                     packet_queue_flush(&is->videoq);
2080                     packet_queue_put(&is->videoq, &flush_pkt);
2081                 }
2082             }
2083             is->seek_req = 0;
2084             eof= 0;
2085         }
2086
2087         /* if the queue are full, no need to read more */
2088         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2089             || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2090                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2091                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2092             /* wait 10 ms */
2093             SDL_Delay(10);
2094             continue;
2095         }
2096         if(url_feof(ic->pb) || eof) {
2097             if(is->video_stream >= 0){
2098                 av_init_packet(pkt);
2099                 pkt->data=NULL;
2100                 pkt->size=0;
2101                 pkt->stream_index= is->video_stream;
2102                 packet_queue_put(&is->videoq, pkt);
2103             }
2104             SDL_Delay(10);
2105             continue;
2106         }
2107         ret = av_read_frame(ic, pkt);
2108         if (ret < 0) {
2109             if (ret == AVERROR_EOF)
2110                 eof=1;
2111             if (url_ferror(ic->pb))
2112                 break;
2113             SDL_Delay(100); /* wait for user event */
2114             continue;
2115         }
2116         if (pkt->stream_index == is->audio_stream) {
2117             packet_queue_put(&is->audioq, pkt);
2118         } else if (pkt->stream_index == is->video_stream) {
2119             packet_queue_put(&is->videoq, pkt);
2120         } else if (pkt->stream_index == is->subtitle_stream) {
2121             packet_queue_put(&is->subtitleq, pkt);
2122         } else {
2123             av_free_packet(pkt);
2124         }
2125     }
2126     /* wait until the end */
2127     while (!is->abort_request) {
2128         SDL_Delay(100);
2129     }
2130
2131     ret = 0;
2132  fail:
2133     /* disable interrupting */
2134     global_video_state = NULL;
2135
2136     /* close each stream */
2137     if (is->audio_stream >= 0)
2138         stream_component_close(is, is->audio_stream);
2139     if (is->video_stream >= 0)
2140         stream_component_close(is, is->video_stream);
2141     if (is->subtitle_stream >= 0)
2142         stream_component_close(is, is->subtitle_stream);
2143     if (is->ic) {
2144         av_close_input_file(is->ic);
2145         is->ic = NULL; /* safety */
2146     }
2147     url_set_interrupt_cb(NULL);
2148
2149     if (ret != 0) {
2150         SDL_Event event;
2151
2152         event.type = FF_QUIT_EVENT;
2153         event.user.data1 = is;
2154         SDL_PushEvent(&event);
2155     }
2156     return 0;
2157 }
2158
2159 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2160 {
2161     VideoState *is;
2162
2163     is = av_mallocz(sizeof(VideoState));
2164     if (!is)
2165         return NULL;
2166     av_strlcpy(is->filename, filename, sizeof(is->filename));
2167     is->iformat = iformat;
2168     is->ytop = 0;
2169     is->xleft = 0;
2170
2171     /* start video display */
2172     is->pictq_mutex = SDL_CreateMutex();
2173     is->pictq_cond = SDL_CreateCond();
2174
2175     is->subpq_mutex = SDL_CreateMutex();
2176     is->subpq_cond = SDL_CreateCond();
2177
2178     is->av_sync_type = av_sync_type;
2179     is->parse_tid = SDL_CreateThread(decode_thread, is);
2180     if (!is->parse_tid) {
2181         av_free(is);
2182         return NULL;
2183     }
2184     return is;
2185 }
2186
2187 static void stream_close(VideoState *is)
2188 {
2189     VideoPicture *vp;
2190     int i;
2191     /* XXX: use a special url_shutdown call to abort parse cleanly */
2192     is->abort_request = 1;
2193     SDL_WaitThread(is->parse_tid, NULL);
2194
2195     /* free all pictures */
2196     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2197         vp = &is->pictq[i];
2198         if (vp->bmp) {
2199             SDL_FreeYUVOverlay(vp->bmp);
2200             vp->bmp = NULL;
2201         }
2202     }
2203     SDL_DestroyMutex(is->pictq_mutex);
2204     SDL_DestroyCond(is->pictq_cond);
2205     SDL_DestroyMutex(is->subpq_mutex);
2206     SDL_DestroyCond(is->subpq_cond);
2207     if (is->img_convert_ctx)
2208         sws_freeContext(is->img_convert_ctx);
2209     av_free(is);
2210 }
2211
2212 static void stream_cycle_channel(VideoState *is, int codec_type)
2213 {
2214     AVFormatContext *ic = is->ic;
2215     int start_index, stream_index;
2216     AVStream *st;
2217
2218     if (codec_type == CODEC_TYPE_VIDEO)
2219         start_index = is->video_stream;
2220     else if (codec_type == CODEC_TYPE_AUDIO)
2221         start_index = is->audio_stream;
2222     else
2223         start_index = is->subtitle_stream;
2224     if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2225         return;
2226     stream_index = start_index;
2227     for(;;) {
2228         if (++stream_index >= is->ic->nb_streams)
2229         {
2230             if (codec_type == CODEC_TYPE_SUBTITLE)
2231             {
2232                 stream_index = -1;
2233                 goto the_end;
2234             } else
2235                 stream_index = 0;
2236         }
2237         if (stream_index == start_index)
2238             return;
2239         st = ic->streams[stream_index];
2240         if (st->codec->codec_type == codec_type) {
2241             /* check that parameters are OK */
2242             switch(codec_type) {
2243             case CODEC_TYPE_AUDIO:
2244                 if (st->codec->sample_rate != 0 &&
2245                     st->codec->channels != 0)
2246                     goto the_end;
2247                 break;
2248             case CODEC_TYPE_VIDEO:
2249             case CODEC_TYPE_SUBTITLE:
2250                 goto the_end;
2251             default:
2252                 break;
2253             }
2254         }
2255     }
2256  the_end:
2257     stream_component_close(is, start_index);
2258     stream_component_open(is, stream_index);
2259 }
2260
2261
2262 static void toggle_full_screen(void)
2263 {
2264     is_full_screen = !is_full_screen;
2265     if (!fs_screen_width) {
2266         /* use default SDL method */
2267 //        SDL_WM_ToggleFullScreen(screen);
2268     }
2269     video_open(cur_stream);
2270 }
2271
2272 static void toggle_pause(void)
2273 {
2274     if (cur_stream)
2275         stream_pause(cur_stream);
2276     step = 0;
2277 }
2278
2279 static void step_to_next_frame(void)
2280 {
2281     if (cur_stream) {
2282         /* if the stream is paused unpause it, then step */
2283         if (cur_stream->paused)
2284             stream_pause(cur_stream);
2285     }
2286     step = 1;
2287 }
2288
2289 static void do_exit(void)
2290 {
2291     int i;
2292     if (cur_stream) {
2293         stream_close(cur_stream);
2294         cur_stream = NULL;
2295     }
2296     for (i = 0; i < CODEC_TYPE_NB; i++)
2297         av_free(avcodec_opts[i]);
2298     av_free(avformat_opts);
2299     av_free(sws_opts);
2300     if (show_status)
2301         printf("\n");
2302     SDL_Quit();
2303     exit(0);
2304 }
2305
2306 static void toggle_audio_display(void)
2307 {
2308     if (cur_stream) {
2309         cur_stream->show_audio = !cur_stream->show_audio;
2310     }
2311 }
2312
2313 /* handle an event sent by the GUI */
2314 static void event_loop(void)
2315 {
2316     SDL_Event event;
2317     double incr, pos, frac;
2318
2319     for(;;) {
2320         SDL_WaitEvent(&event);
2321         switch(event.type) {
2322         case SDL_KEYDOWN:
2323             switch(event.key.keysym.sym) {
2324             case SDLK_ESCAPE:
2325             case SDLK_q:
2326                 do_exit();
2327                 break;
2328             case SDLK_f:
2329                 toggle_full_screen();
2330                 break;
2331             case SDLK_p:
2332             case SDLK_SPACE:
2333                 toggle_pause();
2334                 break;
2335             case SDLK_s: //S: Step to next frame
2336                 step_to_next_frame();
2337                 break;
2338             case SDLK_a:
2339                 if (cur_stream)
2340                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2341                 break;
2342             case SDLK_v:
2343                 if (cur_stream)
2344                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2345                 break;
2346             case SDLK_t:
2347                 if (cur_stream)
2348                     stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2349                 break;
2350             case SDLK_w:
2351                 toggle_audio_display();
2352                 break;
2353             case SDLK_LEFT:
2354                 incr = -10.0;
2355                 goto do_seek;
2356             case SDLK_RIGHT:
2357                 incr = 10.0;
2358                 goto do_seek;
2359             case SDLK_UP:
2360                 incr = 60.0;
2361                 goto do_seek;
2362             case SDLK_DOWN:
2363                 incr = -60.0;
2364             do_seek:
2365                 if (cur_stream) {
2366                     if (seek_by_bytes) {
2367                         if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
2368                             pos= cur_stream->video_current_pos;
2369                         }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
2370                             pos= cur_stream->audio_pkt.pos;
2371                         }else
2372                             pos = url_ftell(cur_stream->ic->pb);
2373                         if (cur_stream->ic->bit_rate)
2374                             incr *= cur_stream->ic->bit_rate / 8.0;
2375                         else
2376                             incr *= 180000.0;
2377                         pos += incr;
2378                         stream_seek(cur_stream, pos, incr, 1);
2379                     } else {
2380                         pos = get_master_clock(cur_stream);
2381                         pos += incr;
2382                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2383                     }
2384                 }
2385                 break;
2386             default:
2387                 break;
2388             }
2389             break;
2390         case SDL_MOUSEBUTTONDOWN:
2391             if (cur_stream) {
2392                 if(seek_by_bytes || cur_stream->ic->duration<=0){
2393                     uint64_t size=  url_fsize(cur_stream->ic->pb);
2394                     stream_seek(cur_stream, size*(double)event.button.x/(double)cur_stream->width, 0, 1);
2395                 }else{
2396                     int64_t ts;
2397                     int ns, hh, mm, ss;
2398                     int tns, thh, tmm, tss;
2399                     tns = cur_stream->ic->duration/1000000LL;
2400                     thh = tns/3600;
2401                     tmm = (tns%3600)/60;
2402                     tss = (tns%60);
2403                     frac = (double)event.button.x/(double)cur_stream->width;
2404                     ns = frac*tns;
2405                     hh = ns/3600;
2406                     mm = (ns%3600)/60;
2407                     ss = (ns%60);
2408                     fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2409                             hh, mm, ss, thh, tmm, tss);
2410                     ts = frac*cur_stream->ic->duration;
2411                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2412                         ts += cur_stream->ic->start_time;
2413                     stream_seek(cur_stream, ts, 0, 0);
2414                 }
2415             }
2416             break;
2417         case SDL_VIDEORESIZE:
2418             if (cur_stream) {
2419                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2420                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2421                 screen_width = cur_stream->width = event.resize.w;
2422                 screen_height= cur_stream->height= event.resize.h;
2423             }
2424             break;
2425         case SDL_QUIT:
2426         case FF_QUIT_EVENT:
2427             do_exit();
2428             break;
2429         case FF_ALLOC_EVENT:
2430             video_open(event.user.data1);
2431             alloc_picture(event.user.data1);
2432             break;
2433         case FF_REFRESH_EVENT:
2434             video_refresh_timer(event.user.data1);
2435             break;
2436         default:
2437             break;
2438         }
2439     }
2440 }
2441
2442 static void opt_frame_size(const char *arg)
2443 {
2444     if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2445         fprintf(stderr, "Incorrect frame size\n");
2446         exit(1);
2447     }
2448     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2449         fprintf(stderr, "Frame size must be a multiple of 2\n");
2450         exit(1);
2451     }
2452 }
2453
2454 static int opt_width(const char *opt, const char *arg)
2455 {
2456     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2457     return 0;
2458 }
2459
2460 static int opt_height(const char *opt, const char *arg)
2461 {
2462     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2463     return 0;
2464 }
2465
2466 static void opt_format(const char *arg)
2467 {
2468     file_iformat = av_find_input_format(arg);
2469     if (!file_iformat) {
2470         fprintf(stderr, "Unknown input format: %s\n", arg);
2471         exit(1);
2472     }
2473 }
2474
2475 static void opt_frame_pix_fmt(const char *arg)
2476 {
2477     frame_pix_fmt = av_get_pix_fmt(arg);
2478 }
2479
2480 static int opt_sync(const char *opt, const char *arg)
2481 {
2482     if (!strcmp(arg, "audio"))
2483         av_sync_type = AV_SYNC_AUDIO_MASTER;
2484     else if (!strcmp(arg, "video"))
2485         av_sync_type = AV_SYNC_VIDEO_MASTER;
2486     else if (!strcmp(arg, "ext"))
2487         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2488     else {
2489         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2490         exit(1);
2491     }
2492     return 0;
2493 }
2494
2495 static int opt_seek(const char *opt, const char *arg)
2496 {
2497     start_time = parse_time_or_die(opt, arg, 1);
2498     return 0;
2499 }
2500
2501 static int opt_debug(const char *opt, const char *arg)
2502 {
2503     av_log_set_level(99);
2504     debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2505     return 0;
2506 }
2507
2508 static int opt_vismv(const char *opt, const char *arg)
2509 {
2510     debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2511     return 0;
2512 }
2513
2514 static int opt_thread_count(const char *opt, const char *arg)
2515 {
2516     thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2517 #if !HAVE_THREADS
2518     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2519 #endif
2520     return 0;
2521 }
2522
2523 static const OptionDef options[] = {
2524 #include "cmdutils_common_opts.h"
2525     { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2526     { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2527     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2528     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2529     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2530     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2531     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2532     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2533     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
2534     { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2535     { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto" },
2536     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2537     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2538     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2539     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2540     { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2541     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2542     { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2543     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2544     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2545     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2546     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2547     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2548     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2549     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2550     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2551     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2552     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2553     { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2554     { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2555     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2556     { NULL, },
2557 };
2558
2559 static void show_usage(void)
2560 {
2561     printf("Simple media player\n");
2562     printf("usage: ffplay [options] input_file\n");
2563     printf("\n");
2564 }
2565
2566 static void show_help(void)
2567 {
2568     show_usage();
2569     show_help_options(options, "Main options:\n",
2570                       OPT_EXPERT, 0);
2571     show_help_options(options, "\nAdvanced options:\n",
2572                       OPT_EXPERT, OPT_EXPERT);
2573     printf("\nWhile playing:\n"
2574            "q, ESC              quit\n"
2575            "f                   toggle full screen\n"
2576            "p, SPC              pause\n"
2577            "a                   cycle audio channel\n"
2578            "v                   cycle video channel\n"
2579            "t                   cycle subtitle channel\n"
2580            "w                   show audio waves\n"
2581            "left/right          seek backward/forward 10 seconds\n"
2582            "down/up             seek backward/forward 1 minute\n"
2583            "mouse click         seek to percentage in file corresponding to fraction of width\n"
2584            );
2585 }
2586
2587 static void opt_input_file(const char *filename)
2588 {
2589     if (!strcmp(filename, "-"))
2590         filename = "pipe:";
2591     input_filename = filename;
2592 }
2593
2594 /* Called from the main */
2595 int main(int argc, char **argv)
2596 {
2597     int flags, i;
2598
2599     /* register all codecs, demux and protocols */
2600     avcodec_register_all();
2601     avdevice_register_all();
2602     av_register_all();
2603
2604     for(i=0; i<CODEC_TYPE_NB; i++){
2605         avcodec_opts[i]= avcodec_alloc_context2(i);
2606     }
2607     avformat_opts = avformat_alloc_context();
2608     sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2609
2610     show_banner();
2611
2612     parse_options(argc, argv, options, opt_input_file);
2613
2614     if (!input_filename) {
2615         show_usage();
2616         fprintf(stderr, "An input file must be specified\n");
2617         fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2618         exit(1);
2619     }
2620
2621     if (display_disable) {
2622         video_disable = 1;
2623     }
2624     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2625 #if !defined(__MINGW32__) && !defined(__APPLE__)
2626     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2627 #endif
2628     if (SDL_Init (flags)) {
2629         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2630         exit(1);
2631     }
2632
2633     if (!display_disable) {
2634 #if HAVE_SDL_VIDEO_SIZE
2635         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2636         fs_screen_width = vi->current_w;
2637         fs_screen_height = vi->current_h;
2638 #endif
2639     }
2640
2641     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2642     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2643     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2644     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2645
2646     av_init_packet(&flush_pkt);
2647     flush_pkt.data= "FLUSH";
2648
2649     cur_stream = stream_open(input_filename, file_iformat);
2650
2651     event_loop();
2652
2653     /* never returns */
2654
2655     return 0;
2656 }