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