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