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