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