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