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