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