]> git.sesse.net Git - ffmpeg/blob - ffplay.c
speedhq: fix out-of-bounds write
[ffmpeg] / ffplay.c
1 /*
2  * Copyright (c) 2003 Fabrice Bellard
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * simple media player based on the FFmpeg libraries
24  */
25
26 #include "config.h"
27 #include <inttypes.h>
28 #include <math.h>
29 #include <limits.h>
30 #include <signal.h>
31 #include <stdint.h>
32
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
49
50 #if CONFIG_AVFILTER
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
54 #endif
55
56 #include <SDL.h>
57 #include <SDL_thread.h>
58
59 #include "cmdutils.h"
60
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_FRAMES 25
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
70
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
75
76 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
78
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
87
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
90
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN  0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX  1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
95
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB   20
98
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
101
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
105
106 #define CURSOR_HIDE_DELAY 1000000
107
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
109
110 static unsigned sws_flags = SWS_BICUBIC;
111
112 typedef struct MyAVPacketList {
113     AVPacket pkt;
114     struct MyAVPacketList *next;
115     int serial;
116 } MyAVPacketList;
117
118 typedef struct PacketQueue {
119     MyAVPacketList *first_pkt, *last_pkt;
120     int nb_packets;
121     int size;
122     int64_t duration;
123     int abort_request;
124     int serial;
125     SDL_mutex *mutex;
126     SDL_cond *cond;
127 } PacketQueue;
128
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
133
134 typedef struct AudioParams {
135     int freq;
136     int channels;
137     int64_t channel_layout;
138     enum AVSampleFormat fmt;
139     int frame_size;
140     int bytes_per_sec;
141 } AudioParams;
142
143 typedef struct Clock {
144     double pts;           /* clock base */
145     double pts_drift;     /* clock base minus time at which we updated the clock */
146     double last_updated;
147     double speed;
148     int serial;           /* clock is based on a packet with this serial */
149     int paused;
150     int *queue_serial;    /* pointer to the current packet queue serial, used for obsolete clock detection */
151 } Clock;
152
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
155     AVFrame *frame;
156     AVSubtitle sub;
157     int serial;
158     double pts;           /* presentation timestamp for the frame */
159     double duration;      /* estimated duration of the frame */
160     int64_t pos;          /* byte position of the frame in the input file */
161     int width;
162     int height;
163     int format;
164     AVRational sar;
165     int uploaded;
166     int flip_v;
167 } Frame;
168
169 typedef struct FrameQueue {
170     Frame queue[FRAME_QUEUE_SIZE];
171     int rindex;
172     int windex;
173     int size;
174     int max_size;
175     int keep_last;
176     int rindex_shown;
177     SDL_mutex *mutex;
178     SDL_cond *cond;
179     PacketQueue *pktq;
180 } FrameQueue;
181
182 enum {
183     AV_SYNC_AUDIO_MASTER, /* default choice */
184     AV_SYNC_VIDEO_MASTER,
185     AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
186 };
187
188 typedef struct Decoder {
189     AVPacket pkt;
190     AVPacket pkt_temp;
191     PacketQueue *queue;
192     AVCodecContext *avctx;
193     int pkt_serial;
194     int finished;
195     int packet_pending;
196     SDL_cond *empty_queue_cond;
197     int64_t start_pts;
198     AVRational start_pts_tb;
199     int64_t next_pts;
200     AVRational next_pts_tb;
201     SDL_Thread *decoder_tid;
202 } Decoder;
203
204 typedef struct VideoState {
205     SDL_Thread *read_tid;
206     AVInputFormat *iformat;
207     int abort_request;
208     int force_refresh;
209     int paused;
210     int last_paused;
211     int queue_attachments_req;
212     int seek_req;
213     int seek_flags;
214     int64_t seek_pos;
215     int64_t seek_rel;
216     int read_pause_return;
217     AVFormatContext *ic;
218     int realtime;
219
220     Clock audclk;
221     Clock vidclk;
222     Clock extclk;
223
224     FrameQueue pictq;
225     FrameQueue subpq;
226     FrameQueue sampq;
227
228     Decoder auddec;
229     Decoder viddec;
230     Decoder subdec;
231
232     int audio_stream;
233
234     int av_sync_type;
235
236     double audio_clock;
237     int audio_clock_serial;
238     double audio_diff_cum; /* used for AV difference average computation */
239     double audio_diff_avg_coef;
240     double audio_diff_threshold;
241     int audio_diff_avg_count;
242     AVStream *audio_st;
243     PacketQueue audioq;
244     int audio_hw_buf_size;
245     uint8_t *audio_buf;
246     uint8_t *audio_buf1;
247     unsigned int audio_buf_size; /* in bytes */
248     unsigned int audio_buf1_size;
249     int audio_buf_index; /* in bytes */
250     int audio_write_buf_size;
251     int audio_volume;
252     int muted;
253     struct AudioParams audio_src;
254 #if CONFIG_AVFILTER
255     struct AudioParams audio_filter_src;
256 #endif
257     struct AudioParams audio_tgt;
258     struct SwrContext *swr_ctx;
259     int frame_drops_early;
260     int frame_drops_late;
261
262     enum ShowMode {
263         SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
264     } show_mode;
265     int16_t sample_array[SAMPLE_ARRAY_SIZE];
266     int sample_array_index;
267     int last_i_start;
268     RDFTContext *rdft;
269     int rdft_bits;
270     FFTSample *rdft_data;
271     int xpos;
272     double last_vis_time;
273     SDL_Texture *vis_texture;
274     SDL_Texture *sub_texture;
275     SDL_Texture *vid_texture;
276
277     int subtitle_stream;
278     AVStream *subtitle_st;
279     PacketQueue subtitleq;
280
281     double frame_timer;
282     double frame_last_returned_time;
283     double frame_last_filter_delay;
284     int video_stream;
285     AVStream *video_st;
286     PacketQueue videoq;
287     double max_frame_duration;      // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
288     struct SwsContext *img_convert_ctx;
289     struct SwsContext *sub_convert_ctx;
290     int eof;
291
292     char *filename;
293     int width, height, xleft, ytop;
294     int step;
295
296 #if CONFIG_AVFILTER
297     int vfilter_idx;
298     AVFilterContext *in_video_filter;   // the first filter in the video chain
299     AVFilterContext *out_video_filter;  // the last filter in the video chain
300     AVFilterContext *in_audio_filter;   // the first filter in the audio chain
301     AVFilterContext *out_audio_filter;  // the last filter in the audio chain
302     AVFilterGraph *agraph;              // audio filter graph
303 #endif
304
305     int last_video_stream, last_audio_stream, last_subtitle_stream;
306
307     SDL_cond *continue_read_thread;
308 } VideoState;
309
310 /* options specified by the user */
311 static AVInputFormat *file_iformat;
312 static const char *input_filename;
313 static const char *window_title;
314 static int default_width  = 640;
315 static int default_height = 480;
316 static int screen_width  = 0;
317 static int screen_height = 0;
318 static int audio_disable;
319 static int video_disable;
320 static int subtitle_disable;
321 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
322 static int seek_by_bytes = -1;
323 static int display_disable;
324 static int borderless;
325 static int startup_volume = 100;
326 static int show_status = 1;
327 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
328 static int64_t start_time = AV_NOPTS_VALUE;
329 static int64_t duration = AV_NOPTS_VALUE;
330 static int fast = 0;
331 static int genpts = 0;
332 static int lowres = 0;
333 static int decoder_reorder_pts = -1;
334 static int autoexit;
335 static int exit_on_keydown;
336 static int exit_on_mousedown;
337 static int loop = 1;
338 static int framedrop = -1;
339 static int infinite_buffer = -1;
340 static enum ShowMode show_mode = SHOW_MODE_NONE;
341 static const char *audio_codec_name;
342 static const char *subtitle_codec_name;
343 static const char *video_codec_name;
344 double rdftspeed = 0.02;
345 static int64_t cursor_last_shown;
346 static int cursor_hidden = 0;
347 #if CONFIG_AVFILTER
348 static const char **vfilters_list = NULL;
349 static int nb_vfilters = 0;
350 static char *afilters = NULL;
351 #endif
352 static int autorotate = 1;
353
354 /* current context */
355 static int is_full_screen;
356 static int64_t audio_callback_time;
357
358 static AVPacket flush_pkt;
359
360 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
361
362 static SDL_Window *window;
363 static SDL_Renderer *renderer;
364
365 #if CONFIG_AVFILTER
366 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
367 {
368     GROW_ARRAY(vfilters_list, nb_vfilters);
369     vfilters_list[nb_vfilters - 1] = arg;
370     return 0;
371 }
372 #endif
373
374 static inline
375 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
376                    enum AVSampleFormat fmt2, int64_t channel_count2)
377 {
378     /* If channel count == 1, planar and non-planar formats are the same */
379     if (channel_count1 == 1 && channel_count2 == 1)
380         return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
381     else
382         return channel_count1 != channel_count2 || fmt1 != fmt2;
383 }
384
385 static inline
386 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
387 {
388     if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
389         return channel_layout;
390     else
391         return 0;
392 }
393
394 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
395 {
396     MyAVPacketList *pkt1;
397
398     if (q->abort_request)
399        return -1;
400
401     pkt1 = av_malloc(sizeof(MyAVPacketList));
402     if (!pkt1)
403         return -1;
404     pkt1->pkt = *pkt;
405     pkt1->next = NULL;
406     if (pkt == &flush_pkt)
407         q->serial++;
408     pkt1->serial = q->serial;
409
410     if (!q->last_pkt)
411         q->first_pkt = pkt1;
412     else
413         q->last_pkt->next = pkt1;
414     q->last_pkt = pkt1;
415     q->nb_packets++;
416     q->size += pkt1->pkt.size + sizeof(*pkt1);
417     q->duration += pkt1->pkt.duration;
418     /* XXX: should duplicate packet data in DV case */
419     SDL_CondSignal(q->cond);
420     return 0;
421 }
422
423 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
424 {
425     int ret;
426
427     SDL_LockMutex(q->mutex);
428     ret = packet_queue_put_private(q, pkt);
429     SDL_UnlockMutex(q->mutex);
430
431     if (pkt != &flush_pkt && ret < 0)
432         av_packet_unref(pkt);
433
434     return ret;
435 }
436
437 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
438 {
439     AVPacket pkt1, *pkt = &pkt1;
440     av_init_packet(pkt);
441     pkt->data = NULL;
442     pkt->size = 0;
443     pkt->stream_index = stream_index;
444     return packet_queue_put(q, pkt);
445 }
446
447 /* packet queue handling */
448 static int packet_queue_init(PacketQueue *q)
449 {
450     memset(q, 0, sizeof(PacketQueue));
451     q->mutex = SDL_CreateMutex();
452     if (!q->mutex) {
453         av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
454         return AVERROR(ENOMEM);
455     }
456     q->cond = SDL_CreateCond();
457     if (!q->cond) {
458         av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
459         return AVERROR(ENOMEM);
460     }
461     q->abort_request = 1;
462     return 0;
463 }
464
465 static void packet_queue_flush(PacketQueue *q)
466 {
467     MyAVPacketList *pkt, *pkt1;
468
469     SDL_LockMutex(q->mutex);
470     for (pkt = q->first_pkt; pkt; pkt = pkt1) {
471         pkt1 = pkt->next;
472         av_packet_unref(&pkt->pkt);
473         av_freep(&pkt);
474     }
475     q->last_pkt = NULL;
476     q->first_pkt = NULL;
477     q->nb_packets = 0;
478     q->size = 0;
479     q->duration = 0;
480     SDL_UnlockMutex(q->mutex);
481 }
482
483 static void packet_queue_destroy(PacketQueue *q)
484 {
485     packet_queue_flush(q);
486     SDL_DestroyMutex(q->mutex);
487     SDL_DestroyCond(q->cond);
488 }
489
490 static void packet_queue_abort(PacketQueue *q)
491 {
492     SDL_LockMutex(q->mutex);
493
494     q->abort_request = 1;
495
496     SDL_CondSignal(q->cond);
497
498     SDL_UnlockMutex(q->mutex);
499 }
500
501 static void packet_queue_start(PacketQueue *q)
502 {
503     SDL_LockMutex(q->mutex);
504     q->abort_request = 0;
505     packet_queue_put_private(q, &flush_pkt);
506     SDL_UnlockMutex(q->mutex);
507 }
508
509 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
510 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
511 {
512     MyAVPacketList *pkt1;
513     int ret;
514
515     SDL_LockMutex(q->mutex);
516
517     for (;;) {
518         if (q->abort_request) {
519             ret = -1;
520             break;
521         }
522
523         pkt1 = q->first_pkt;
524         if (pkt1) {
525             q->first_pkt = pkt1->next;
526             if (!q->first_pkt)
527                 q->last_pkt = NULL;
528             q->nb_packets--;
529             q->size -= pkt1->pkt.size + sizeof(*pkt1);
530             q->duration -= pkt1->pkt.duration;
531             *pkt = pkt1->pkt;
532             if (serial)
533                 *serial = pkt1->serial;
534             av_free(pkt1);
535             ret = 1;
536             break;
537         } else if (!block) {
538             ret = 0;
539             break;
540         } else {
541             SDL_CondWait(q->cond, q->mutex);
542         }
543     }
544     SDL_UnlockMutex(q->mutex);
545     return ret;
546 }
547
548 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
549     memset(d, 0, sizeof(Decoder));
550     d->avctx = avctx;
551     d->queue = queue;
552     d->empty_queue_cond = empty_queue_cond;
553     d->start_pts = AV_NOPTS_VALUE;
554 }
555
556 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
557     int got_frame = 0;
558
559     do {
560         int ret = -1;
561
562         if (d->queue->abort_request)
563             return -1;
564
565         if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
566             AVPacket pkt;
567             do {
568                 if (d->queue->nb_packets == 0)
569                     SDL_CondSignal(d->empty_queue_cond);
570                 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
571                     return -1;
572                 if (pkt.data == flush_pkt.data) {
573                     avcodec_flush_buffers(d->avctx);
574                     d->finished = 0;
575                     d->next_pts = d->start_pts;
576                     d->next_pts_tb = d->start_pts_tb;
577                 }
578             } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
579             av_packet_unref(&d->pkt);
580             d->pkt_temp = d->pkt = pkt;
581             d->packet_pending = 1;
582         }
583
584         switch (d->avctx->codec_type) {
585             case AVMEDIA_TYPE_VIDEO:
586                 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
587                 if (got_frame) {
588                     if (decoder_reorder_pts == -1) {
589                         frame->pts = av_frame_get_best_effort_timestamp(frame);
590                     } else if (!decoder_reorder_pts) {
591                         frame->pts = frame->pkt_dts;
592                     }
593                 }
594                 break;
595             case AVMEDIA_TYPE_AUDIO:
596                 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
597                 if (got_frame) {
598                     AVRational tb = (AVRational){1, frame->sample_rate};
599                     if (frame->pts != AV_NOPTS_VALUE)
600                         frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
601                     else if (d->next_pts != AV_NOPTS_VALUE)
602                         frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
603                     if (frame->pts != AV_NOPTS_VALUE) {
604                         d->next_pts = frame->pts + frame->nb_samples;
605                         d->next_pts_tb = tb;
606                     }
607                 }
608                 break;
609             case AVMEDIA_TYPE_SUBTITLE:
610                 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
611                 break;
612         }
613
614         if (ret < 0) {
615             d->packet_pending = 0;
616         } else {
617             d->pkt_temp.dts =
618             d->pkt_temp.pts = AV_NOPTS_VALUE;
619             if (d->pkt_temp.data) {
620                 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
621                     ret = d->pkt_temp.size;
622                 d->pkt_temp.data += ret;
623                 d->pkt_temp.size -= ret;
624                 if (d->pkt_temp.size <= 0)
625                     d->packet_pending = 0;
626             } else {
627                 if (!got_frame) {
628                     d->packet_pending = 0;
629                     d->finished = d->pkt_serial;
630                 }
631             }
632         }
633     } while (!got_frame && !d->finished);
634
635     return got_frame;
636 }
637
638 static void decoder_destroy(Decoder *d) {
639     av_packet_unref(&d->pkt);
640     avcodec_free_context(&d->avctx);
641 }
642
643 static void frame_queue_unref_item(Frame *vp)
644 {
645     av_frame_unref(vp->frame);
646     avsubtitle_free(&vp->sub);
647 }
648
649 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
650 {
651     int i;
652     memset(f, 0, sizeof(FrameQueue));
653     if (!(f->mutex = SDL_CreateMutex())) {
654         av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
655         return AVERROR(ENOMEM);
656     }
657     if (!(f->cond = SDL_CreateCond())) {
658         av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
659         return AVERROR(ENOMEM);
660     }
661     f->pktq = pktq;
662     f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
663     f->keep_last = !!keep_last;
664     for (i = 0; i < f->max_size; i++)
665         if (!(f->queue[i].frame = av_frame_alloc()))
666             return AVERROR(ENOMEM);
667     return 0;
668 }
669
670 static void frame_queue_destory(FrameQueue *f)
671 {
672     int i;
673     for (i = 0; i < f->max_size; i++) {
674         Frame *vp = &f->queue[i];
675         frame_queue_unref_item(vp);
676         av_frame_free(&vp->frame);
677     }
678     SDL_DestroyMutex(f->mutex);
679     SDL_DestroyCond(f->cond);
680 }
681
682 static void frame_queue_signal(FrameQueue *f)
683 {
684     SDL_LockMutex(f->mutex);
685     SDL_CondSignal(f->cond);
686     SDL_UnlockMutex(f->mutex);
687 }
688
689 static Frame *frame_queue_peek(FrameQueue *f)
690 {
691     return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
692 }
693
694 static Frame *frame_queue_peek_next(FrameQueue *f)
695 {
696     return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
697 }
698
699 static Frame *frame_queue_peek_last(FrameQueue *f)
700 {
701     return &f->queue[f->rindex];
702 }
703
704 static Frame *frame_queue_peek_writable(FrameQueue *f)
705 {
706     /* wait until we have space to put a new frame */
707     SDL_LockMutex(f->mutex);
708     while (f->size >= f->max_size &&
709            !f->pktq->abort_request) {
710         SDL_CondWait(f->cond, f->mutex);
711     }
712     SDL_UnlockMutex(f->mutex);
713
714     if (f->pktq->abort_request)
715         return NULL;
716
717     return &f->queue[f->windex];
718 }
719
720 static Frame *frame_queue_peek_readable(FrameQueue *f)
721 {
722     /* wait until we have a readable a new frame */
723     SDL_LockMutex(f->mutex);
724     while (f->size - f->rindex_shown <= 0 &&
725            !f->pktq->abort_request) {
726         SDL_CondWait(f->cond, f->mutex);
727     }
728     SDL_UnlockMutex(f->mutex);
729
730     if (f->pktq->abort_request)
731         return NULL;
732
733     return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
734 }
735
736 static void frame_queue_push(FrameQueue *f)
737 {
738     if (++f->windex == f->max_size)
739         f->windex = 0;
740     SDL_LockMutex(f->mutex);
741     f->size++;
742     SDL_CondSignal(f->cond);
743     SDL_UnlockMutex(f->mutex);
744 }
745
746 static void frame_queue_next(FrameQueue *f)
747 {
748     if (f->keep_last && !f->rindex_shown) {
749         f->rindex_shown = 1;
750         return;
751     }
752     frame_queue_unref_item(&f->queue[f->rindex]);
753     if (++f->rindex == f->max_size)
754         f->rindex = 0;
755     SDL_LockMutex(f->mutex);
756     f->size--;
757     SDL_CondSignal(f->cond);
758     SDL_UnlockMutex(f->mutex);
759 }
760
761 /* return the number of undisplayed frames in the queue */
762 static int frame_queue_nb_remaining(FrameQueue *f)
763 {
764     return f->size - f->rindex_shown;
765 }
766
767 /* return last shown position */
768 static int64_t frame_queue_last_pos(FrameQueue *f)
769 {
770     Frame *fp = &f->queue[f->rindex];
771     if (f->rindex_shown && fp->serial == f->pktq->serial)
772         return fp->pos;
773     else
774         return -1;
775 }
776
777 static void decoder_abort(Decoder *d, FrameQueue *fq)
778 {
779     packet_queue_abort(d->queue);
780     frame_queue_signal(fq);
781     SDL_WaitThread(d->decoder_tid, NULL);
782     d->decoder_tid = NULL;
783     packet_queue_flush(d->queue);
784 }
785
786 static inline void fill_rectangle(int x, int y, int w, int h)
787 {
788     SDL_Rect rect;
789     rect.x = x;
790     rect.y = y;
791     rect.w = w;
792     rect.h = h;
793     if (w && h)
794         SDL_RenderFillRect(renderer, &rect);
795 }
796
797 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
798 {
799     Uint32 format;
800     int access, w, h;
801     if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
802         void *pixels;
803         int pitch;
804         SDL_DestroyTexture(*texture);
805         if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
806             return -1;
807         if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
808             return -1;
809         if (init_texture) {
810             if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
811                 return -1;
812             memset(pixels, 0, pitch * new_height);
813             SDL_UnlockTexture(*texture);
814         }
815     }
816     return 0;
817 }
818
819 static void calculate_display_rect(SDL_Rect *rect,
820                                    int scr_xleft, int scr_ytop, int scr_width, int scr_height,
821                                    int pic_width, int pic_height, AVRational pic_sar)
822 {
823     float aspect_ratio;
824     int width, height, x, y;
825
826     if (pic_sar.num == 0)
827         aspect_ratio = 0;
828     else
829         aspect_ratio = av_q2d(pic_sar);
830
831     if (aspect_ratio <= 0.0)
832         aspect_ratio = 1.0;
833     aspect_ratio *= (float)pic_width / (float)pic_height;
834
835     /* XXX: we suppose the screen has a 1.0 pixel ratio */
836     height = scr_height;
837     width = lrint(height * aspect_ratio) & ~1;
838     if (width > scr_width) {
839         width = scr_width;
840         height = lrint(width / aspect_ratio) & ~1;
841     }
842     x = (scr_width - width) / 2;
843     y = (scr_height - height) / 2;
844     rect->x = scr_xleft + x;
845     rect->y = scr_ytop  + y;
846     rect->w = FFMAX(width,  1);
847     rect->h = FFMAX(height, 1);
848 }
849
850 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
851     int ret = 0;
852     switch (frame->format) {
853         case AV_PIX_FMT_YUV420P:
854             if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
855                 av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
856                 return -1;
857             }
858             ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
859                                                   frame->data[1], frame->linesize[1],
860                                                   frame->data[2], frame->linesize[2]);
861             break;
862         case AV_PIX_FMT_BGRA:
863             if (frame->linesize[0] < 0) {
864                 ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
865             } else {
866                 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
867             }
868             break;
869         default:
870             /* This should only happen if we are not using avfilter... */
871             *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
872                 frame->width, frame->height, frame->format, frame->width, frame->height,
873                 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
874             if (*img_convert_ctx != NULL) {
875                 uint8_t *pixels[4];
876                 int pitch[4];
877                 if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) {
878                     sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
879                               0, frame->height, pixels, pitch);
880                     SDL_UnlockTexture(tex);
881                 }
882             } else {
883                 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
884                 ret = -1;
885             }
886             break;
887     }
888     return ret;
889 }
890
891 static void video_image_display(VideoState *is)
892 {
893     Frame *vp;
894     Frame *sp = NULL;
895     SDL_Rect rect;
896
897     vp = frame_queue_peek_last(&is->pictq);
898     if (is->subtitle_st) {
899         if (frame_queue_nb_remaining(&is->subpq) > 0) {
900             sp = frame_queue_peek(&is->subpq);
901
902             if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
903                 if (!sp->uploaded) {
904                     uint8_t* pixels[4];
905                     int pitch[4];
906                     int i;
907                     if (!sp->width || !sp->height) {
908                         sp->width = vp->width;
909                         sp->height = vp->height;
910                     }
911                     if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
912                         return;
913
914                     for (i = 0; i < sp->sub.num_rects; i++) {
915                         AVSubtitleRect *sub_rect = sp->sub.rects[i];
916
917                         sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
918                         sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
919                         sub_rect->w = av_clip(sub_rect->w, 0, sp->width  - sub_rect->x);
920                         sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
921
922                         is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
923                             sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
924                             sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
925                             0, NULL, NULL, NULL);
926                         if (!is->sub_convert_ctx) {
927                             av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
928                             return;
929                         }
930                         if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
931                             sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
932                                       0, sub_rect->h, pixels, pitch);
933                             SDL_UnlockTexture(is->sub_texture);
934                         }
935                     }
936                     sp->uploaded = 1;
937                 }
938             } else
939                 sp = NULL;
940         }
941     }
942
943     calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
944
945     if (!vp->uploaded) {
946         int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888;
947         if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0)
948             return;
949         if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
950             return;
951         vp->uploaded = 1;
952         vp->flip_v = vp->frame->linesize[0] < 0;
953     }
954
955     SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
956     if (sp) {
957 #if USE_ONEPASS_SUBTITLE_RENDER
958         SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
959 #else
960         int i;
961         double xratio = (double)rect.w / (double)sp->width;
962         double yratio = (double)rect.h / (double)sp->height;
963         for (i = 0; i < sp->sub.num_rects; i++) {
964             SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
965             SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
966                                .y = rect.y + sub_rect->y * yratio,
967                                .w = sub_rect->w * xratio,
968                                .h = sub_rect->h * yratio};
969             SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
970         }
971 #endif
972     }
973 }
974
975 static inline int compute_mod(int a, int b)
976 {
977     return a < 0 ? a%b + b : a%b;
978 }
979
980 static void video_audio_display(VideoState *s)
981 {
982     int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
983     int ch, channels, h, h2;
984     int64_t time_diff;
985     int rdft_bits, nb_freq;
986
987     for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
988         ;
989     nb_freq = 1 << (rdft_bits - 1);
990
991     /* compute display index : center on currently output samples */
992     channels = s->audio_tgt.channels;
993     nb_display_channels = channels;
994     if (!s->paused) {
995         int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
996         n = 2 * channels;
997         delay = s->audio_write_buf_size;
998         delay /= n;
999
1000         /* to be more precise, we take into account the time spent since
1001            the last buffer computation */
1002         if (audio_callback_time) {
1003             time_diff = av_gettime_relative() - audio_callback_time;
1004             delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1005         }
1006
1007         delay += 2 * data_used;
1008         if (delay < data_used)
1009             delay = data_used;
1010
1011         i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1012         if (s->show_mode == SHOW_MODE_WAVES) {
1013             h = INT_MIN;
1014             for (i = 0; i < 1000; i += channels) {
1015                 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1016                 int a = s->sample_array[idx];
1017                 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1018                 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1019                 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1020                 int score = a - d;
1021                 if (h < score && (b ^ c) < 0) {
1022                     h = score;
1023                     i_start = idx;
1024                 }
1025             }
1026         }
1027
1028         s->last_i_start = i_start;
1029     } else {
1030         i_start = s->last_i_start;
1031     }
1032
1033     if (s->show_mode == SHOW_MODE_WAVES) {
1034         SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1035
1036         /* total height for one channel */
1037         h = s->height / nb_display_channels;
1038         /* graph height / 2 */
1039         h2 = (h * 9) / 20;
1040         for (ch = 0; ch < nb_display_channels; ch++) {
1041             i = i_start + ch;
1042             y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1043             for (x = 0; x < s->width; x++) {
1044                 y = (s->sample_array[i] * h2) >> 15;
1045                 if (y < 0) {
1046                     y = -y;
1047                     ys = y1 - y;
1048                 } else {
1049                     ys = y1;
1050                 }
1051                 fill_rectangle(s->xleft + x, ys, 1, y);
1052                 i += channels;
1053                 if (i >= SAMPLE_ARRAY_SIZE)
1054                     i -= SAMPLE_ARRAY_SIZE;
1055             }
1056         }
1057
1058         SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1059
1060         for (ch = 1; ch < nb_display_channels; ch++) {
1061             y = s->ytop + ch * h;
1062             fill_rectangle(s->xleft, y, s->width, 1);
1063         }
1064     } else {
1065         if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1066             return;
1067
1068         nb_display_channels= FFMIN(nb_display_channels, 2);
1069         if (rdft_bits != s->rdft_bits) {
1070             av_rdft_end(s->rdft);
1071             av_free(s->rdft_data);
1072             s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1073             s->rdft_bits = rdft_bits;
1074             s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1075         }
1076         if (!s->rdft || !s->rdft_data){
1077             av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1078             s->show_mode = SHOW_MODE_WAVES;
1079         } else {
1080             FFTSample *data[2];
1081             SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1082             uint32_t *pixels;
1083             int pitch;
1084             for (ch = 0; ch < nb_display_channels; ch++) {
1085                 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1086                 i = i_start + ch;
1087                 for (x = 0; x < 2 * nb_freq; x++) {
1088                     double w = (x-nb_freq) * (1.0 / nb_freq);
1089                     data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1090                     i += channels;
1091                     if (i >= SAMPLE_ARRAY_SIZE)
1092                         i -= SAMPLE_ARRAY_SIZE;
1093                 }
1094                 av_rdft_calc(s->rdft, data[ch]);
1095             }
1096             /* Least efficient way to do this, we should of course
1097              * directly access it but it is more than fast enough. */
1098             if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1099                 pitch >>= 2;
1100                 pixels += pitch * s->height;
1101                 for (y = 0; y < s->height; y++) {
1102                     double w = 1 / sqrt(nb_freq);
1103                     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]));
1104                     int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1105                                                         : a;
1106                     a = FFMIN(a, 255);
1107                     b = FFMIN(b, 255);
1108                     pixels -= pitch;
1109                     *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1110                 }
1111                 SDL_UnlockTexture(s->vis_texture);
1112             }
1113             SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1114         }
1115         if (!s->paused)
1116             s->xpos++;
1117         if (s->xpos >= s->width)
1118             s->xpos= s->xleft;
1119     }
1120 }
1121
1122 static void stream_component_close(VideoState *is, int stream_index)
1123 {
1124     AVFormatContext *ic = is->ic;
1125     AVCodecParameters *codecpar;
1126
1127     if (stream_index < 0 || stream_index >= ic->nb_streams)
1128         return;
1129     codecpar = ic->streams[stream_index]->codecpar;
1130
1131     switch (codecpar->codec_type) {
1132     case AVMEDIA_TYPE_AUDIO:
1133         decoder_abort(&is->auddec, &is->sampq);
1134         SDL_CloseAudio();
1135         decoder_destroy(&is->auddec);
1136         swr_free(&is->swr_ctx);
1137         av_freep(&is->audio_buf1);
1138         is->audio_buf1_size = 0;
1139         is->audio_buf = NULL;
1140
1141         if (is->rdft) {
1142             av_rdft_end(is->rdft);
1143             av_freep(&is->rdft_data);
1144             is->rdft = NULL;
1145             is->rdft_bits = 0;
1146         }
1147         break;
1148     case AVMEDIA_TYPE_VIDEO:
1149         decoder_abort(&is->viddec, &is->pictq);
1150         decoder_destroy(&is->viddec);
1151         break;
1152     case AVMEDIA_TYPE_SUBTITLE:
1153         decoder_abort(&is->subdec, &is->subpq);
1154         decoder_destroy(&is->subdec);
1155         break;
1156     default:
1157         break;
1158     }
1159
1160     ic->streams[stream_index]->discard = AVDISCARD_ALL;
1161     switch (codecpar->codec_type) {
1162     case AVMEDIA_TYPE_AUDIO:
1163         is->audio_st = NULL;
1164         is->audio_stream = -1;
1165         break;
1166     case AVMEDIA_TYPE_VIDEO:
1167         is->video_st = NULL;
1168         is->video_stream = -1;
1169         break;
1170     case AVMEDIA_TYPE_SUBTITLE:
1171         is->subtitle_st = NULL;
1172         is->subtitle_stream = -1;
1173         break;
1174     default:
1175         break;
1176     }
1177 }
1178
1179 static void stream_close(VideoState *is)
1180 {
1181     /* XXX: use a special url_shutdown call to abort parse cleanly */
1182     is->abort_request = 1;
1183     SDL_WaitThread(is->read_tid, NULL);
1184
1185     /* close each stream */
1186     if (is->audio_stream >= 0)
1187         stream_component_close(is, is->audio_stream);
1188     if (is->video_stream >= 0)
1189         stream_component_close(is, is->video_stream);
1190     if (is->subtitle_stream >= 0)
1191         stream_component_close(is, is->subtitle_stream);
1192
1193     avformat_close_input(&is->ic);
1194
1195     packet_queue_destroy(&is->videoq);
1196     packet_queue_destroy(&is->audioq);
1197     packet_queue_destroy(&is->subtitleq);
1198
1199     /* free all pictures */
1200     frame_queue_destory(&is->pictq);
1201     frame_queue_destory(&is->sampq);
1202     frame_queue_destory(&is->subpq);
1203     SDL_DestroyCond(is->continue_read_thread);
1204     sws_freeContext(is->img_convert_ctx);
1205     sws_freeContext(is->sub_convert_ctx);
1206     av_free(is->filename);
1207     if (is->vis_texture)
1208         SDL_DestroyTexture(is->vis_texture);
1209     if (is->vid_texture)
1210         SDL_DestroyTexture(is->vid_texture);
1211     if (is->sub_texture)
1212         SDL_DestroyTexture(is->sub_texture);
1213     av_free(is);
1214 }
1215
1216 static void do_exit(VideoState *is)
1217 {
1218     if (is) {
1219         stream_close(is);
1220     }
1221     if (renderer)
1222         SDL_DestroyRenderer(renderer);
1223     if (window)
1224         SDL_DestroyWindow(window);
1225     av_lockmgr_register(NULL);
1226     uninit_opts();
1227 #if CONFIG_AVFILTER
1228     av_freep(&vfilters_list);
1229 #endif
1230     avformat_network_deinit();
1231     if (show_status)
1232         printf("\n");
1233     SDL_Quit();
1234     av_log(NULL, AV_LOG_QUIET, "%s", "");
1235     exit(0);
1236 }
1237
1238 static void sigterm_handler(int sig)
1239 {
1240     exit(123);
1241 }
1242
1243 static void set_default_window_size(int width, int height, AVRational sar)
1244 {
1245     SDL_Rect rect;
1246     calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1247     default_width  = rect.w;
1248     default_height = rect.h;
1249 }
1250
1251 static int video_open(VideoState *is)
1252 {
1253     int w,h;
1254
1255     if (screen_width) {
1256         w = screen_width;
1257         h = screen_height;
1258     } else {
1259         w = default_width;
1260         h = default_height;
1261     }
1262
1263     if (!window) {
1264         int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
1265         if (!window_title)
1266             window_title = input_filename;
1267         if (is_full_screen)
1268             flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1269         if (borderless)
1270             flags |= SDL_WINDOW_BORDERLESS;
1271         window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1272         SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1273         if (window) {
1274             SDL_RendererInfo info;
1275             renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1276             if (!renderer) {
1277                 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1278                 renderer = SDL_CreateRenderer(window, -1, 0);
1279             }
1280             if (renderer) {
1281                 if (!SDL_GetRendererInfo(renderer, &info))
1282                     av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1283             }
1284         }
1285     } else {
1286         SDL_SetWindowSize(window, w, h);
1287     }
1288
1289     if (!window || !renderer) {
1290         av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1291         do_exit(is);
1292     }
1293
1294     is->width  = w;
1295     is->height = h;
1296
1297     return 0;
1298 }
1299
1300 /* display the current picture, if any */
1301 static void video_display(VideoState *is)
1302 {
1303     if (!window)
1304         video_open(is);
1305
1306     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1307     SDL_RenderClear(renderer);
1308     if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1309         video_audio_display(is);
1310     else if (is->video_st)
1311         video_image_display(is);
1312     SDL_RenderPresent(renderer);
1313 }
1314
1315 static double get_clock(Clock *c)
1316 {
1317     if (*c->queue_serial != c->serial)
1318         return NAN;
1319     if (c->paused) {
1320         return c->pts;
1321     } else {
1322         double time = av_gettime_relative() / 1000000.0;
1323         return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1324     }
1325 }
1326
1327 static void set_clock_at(Clock *c, double pts, int serial, double time)
1328 {
1329     c->pts = pts;
1330     c->last_updated = time;
1331     c->pts_drift = c->pts - time;
1332     c->serial = serial;
1333 }
1334
1335 static void set_clock(Clock *c, double pts, int serial)
1336 {
1337     double time = av_gettime_relative() / 1000000.0;
1338     set_clock_at(c, pts, serial, time);
1339 }
1340
1341 static void set_clock_speed(Clock *c, double speed)
1342 {
1343     set_clock(c, get_clock(c), c->serial);
1344     c->speed = speed;
1345 }
1346
1347 static void init_clock(Clock *c, int *queue_serial)
1348 {
1349     c->speed = 1.0;
1350     c->paused = 0;
1351     c->queue_serial = queue_serial;
1352     set_clock(c, NAN, -1);
1353 }
1354
1355 static void sync_clock_to_slave(Clock *c, Clock *slave)
1356 {
1357     double clock = get_clock(c);
1358     double slave_clock = get_clock(slave);
1359     if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1360         set_clock(c, slave_clock, slave->serial);
1361 }
1362
1363 static int get_master_sync_type(VideoState *is) {
1364     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1365         if (is->video_st)
1366             return AV_SYNC_VIDEO_MASTER;
1367         else
1368             return AV_SYNC_AUDIO_MASTER;
1369     } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1370         if (is->audio_st)
1371             return AV_SYNC_AUDIO_MASTER;
1372         else
1373             return AV_SYNC_EXTERNAL_CLOCK;
1374     } else {
1375         return AV_SYNC_EXTERNAL_CLOCK;
1376     }
1377 }
1378
1379 /* get the current master clock value */
1380 static double get_master_clock(VideoState *is)
1381 {
1382     double val;
1383
1384     switch (get_master_sync_type(is)) {
1385         case AV_SYNC_VIDEO_MASTER:
1386             val = get_clock(&is->vidclk);
1387             break;
1388         case AV_SYNC_AUDIO_MASTER:
1389             val = get_clock(&is->audclk);
1390             break;
1391         default:
1392             val = get_clock(&is->extclk);
1393             break;
1394     }
1395     return val;
1396 }
1397
1398 static void check_external_clock_speed(VideoState *is) {
1399    if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1400        is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1401        set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1402    } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1403               (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1404        set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1405    } else {
1406        double speed = is->extclk.speed;
1407        if (speed != 1.0)
1408            set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1409    }
1410 }
1411
1412 /* seek in the stream */
1413 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1414 {
1415     if (!is->seek_req) {
1416         is->seek_pos = pos;
1417         is->seek_rel = rel;
1418         is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1419         if (seek_by_bytes)
1420             is->seek_flags |= AVSEEK_FLAG_BYTE;
1421         is->seek_req = 1;
1422         SDL_CondSignal(is->continue_read_thread);
1423     }
1424 }
1425
1426 /* pause or resume the video */
1427 static void stream_toggle_pause(VideoState *is)
1428 {
1429     if (is->paused) {
1430         is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1431         if (is->read_pause_return != AVERROR(ENOSYS)) {
1432             is->vidclk.paused = 0;
1433         }
1434         set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1435     }
1436     set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1437     is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1438 }
1439
1440 static void toggle_pause(VideoState *is)
1441 {
1442     stream_toggle_pause(is);
1443     is->step = 0;
1444 }
1445
1446 static void toggle_mute(VideoState *is)
1447 {
1448     is->muted = !is->muted;
1449 }
1450
1451 static void update_volume(VideoState *is, int sign, int step)
1452 {
1453     is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1454 }
1455
1456 static void step_to_next_frame(VideoState *is)
1457 {
1458     /* if the stream is paused unpause it, then step */
1459     if (is->paused)
1460         stream_toggle_pause(is);
1461     is->step = 1;
1462 }
1463
1464 static double compute_target_delay(double delay, VideoState *is)
1465 {
1466     double sync_threshold, diff = 0;
1467
1468     /* update delay to follow master synchronisation source */
1469     if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1470         /* if video is slave, we try to correct big delays by
1471            duplicating or deleting a frame */
1472         diff = get_clock(&is->vidclk) - get_master_clock(is);
1473
1474         /* skip or repeat frame. We take into account the
1475            delay to compute the threshold. I still don't know
1476            if it is the best guess */
1477         sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1478         if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1479             if (diff <= -sync_threshold)
1480                 delay = FFMAX(0, delay + diff);
1481             else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1482                 delay = delay + diff;
1483             else if (diff >= sync_threshold)
1484                 delay = 2 * delay;
1485         }
1486     }
1487
1488     av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1489             delay, -diff);
1490
1491     return delay;
1492 }
1493
1494 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1495     if (vp->serial == nextvp->serial) {
1496         double duration = nextvp->pts - vp->pts;
1497         if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1498             return vp->duration;
1499         else
1500             return duration;
1501     } else {
1502         return 0.0;
1503     }
1504 }
1505
1506 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1507     /* update current video pts */
1508     set_clock(&is->vidclk, pts, serial);
1509     sync_clock_to_slave(&is->extclk, &is->vidclk);
1510 }
1511
1512 /* called to display each frame */
1513 static void video_refresh(void *opaque, double *remaining_time)
1514 {
1515     VideoState *is = opaque;
1516     double time;
1517
1518     Frame *sp, *sp2;
1519
1520     if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1521         check_external_clock_speed(is);
1522
1523     if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1524         time = av_gettime_relative() / 1000000.0;
1525         if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1526             video_display(is);
1527             is->last_vis_time = time;
1528         }
1529         *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1530     }
1531
1532     if (is->video_st) {
1533 retry:
1534         if (frame_queue_nb_remaining(&is->pictq) == 0) {
1535             // nothing to do, no picture to display in the queue
1536         } else {
1537             double last_duration, duration, delay;
1538             Frame *vp, *lastvp;
1539
1540             /* dequeue the picture */
1541             lastvp = frame_queue_peek_last(&is->pictq);
1542             vp = frame_queue_peek(&is->pictq);
1543
1544             if (vp->serial != is->videoq.serial) {
1545                 frame_queue_next(&is->pictq);
1546                 goto retry;
1547             }
1548
1549             if (lastvp->serial != vp->serial)
1550                 is->frame_timer = av_gettime_relative() / 1000000.0;
1551
1552             if (is->paused)
1553                 goto display;
1554
1555             /* compute nominal last_duration */
1556             last_duration = vp_duration(is, lastvp, vp);
1557             delay = compute_target_delay(last_duration, is);
1558
1559             time= av_gettime_relative()/1000000.0;
1560             if (time < is->frame_timer + delay) {
1561                 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1562                 goto display;
1563             }
1564
1565             is->frame_timer += delay;
1566             if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1567                 is->frame_timer = time;
1568
1569             SDL_LockMutex(is->pictq.mutex);
1570             if (!isnan(vp->pts))
1571                 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1572             SDL_UnlockMutex(is->pictq.mutex);
1573
1574             if (frame_queue_nb_remaining(&is->pictq) > 1) {
1575                 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1576                 duration = vp_duration(is, vp, nextvp);
1577                 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1578                     is->frame_drops_late++;
1579                     frame_queue_next(&is->pictq);
1580                     goto retry;
1581                 }
1582             }
1583
1584             if (is->subtitle_st) {
1585                     while (frame_queue_nb_remaining(&is->subpq) > 0) {
1586                         sp = frame_queue_peek(&is->subpq);
1587
1588                         if (frame_queue_nb_remaining(&is->subpq) > 1)
1589                             sp2 = frame_queue_peek_next(&is->subpq);
1590                         else
1591                             sp2 = NULL;
1592
1593                         if (sp->serial != is->subtitleq.serial
1594                                 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1595                                 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1596                         {
1597                             if (sp->uploaded) {
1598                                 int i;
1599                                 for (i = 0; i < sp->sub.num_rects; i++) {
1600                                     AVSubtitleRect *sub_rect = sp->sub.rects[i];
1601                                     uint8_t *pixels;
1602                                     int pitch, j;
1603
1604                                     if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1605                                         for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1606                                             memset(pixels, 0, sub_rect->w << 2);
1607                                         SDL_UnlockTexture(is->sub_texture);
1608                                     }
1609                                 }
1610                             }
1611                             frame_queue_next(&is->subpq);
1612                         } else {
1613                             break;
1614                         }
1615                     }
1616             }
1617
1618             frame_queue_next(&is->pictq);
1619             is->force_refresh = 1;
1620
1621             if (is->step && !is->paused)
1622                 stream_toggle_pause(is);
1623         }
1624 display:
1625         /* display picture */
1626         if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1627             video_display(is);
1628     }
1629     is->force_refresh = 0;
1630     if (show_status) {
1631         static int64_t last_time;
1632         int64_t cur_time;
1633         int aqsize, vqsize, sqsize;
1634         double av_diff;
1635
1636         cur_time = av_gettime_relative();
1637         if (!last_time || (cur_time - last_time) >= 30000) {
1638             aqsize = 0;
1639             vqsize = 0;
1640             sqsize = 0;
1641             if (is->audio_st)
1642                 aqsize = is->audioq.size;
1643             if (is->video_st)
1644                 vqsize = is->videoq.size;
1645             if (is->subtitle_st)
1646                 sqsize = is->subtitleq.size;
1647             av_diff = 0;
1648             if (is->audio_st && is->video_st)
1649                 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1650             else if (is->video_st)
1651                 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1652             else if (is->audio_st)
1653                 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1654             av_log(NULL, AV_LOG_INFO,
1655                    "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
1656                    get_master_clock(is),
1657                    (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : "   ")),
1658                    av_diff,
1659                    is->frame_drops_early + is->frame_drops_late,
1660                    aqsize / 1024,
1661                    vqsize / 1024,
1662                    sqsize,
1663                    is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1664                    is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1665             fflush(stdout);
1666             last_time = cur_time;
1667         }
1668     }
1669 }
1670
1671 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1672 {
1673     Frame *vp;
1674
1675 #if defined(DEBUG_SYNC)
1676     printf("frame_type=%c pts=%0.3f\n",
1677            av_get_picture_type_char(src_frame->pict_type), pts);
1678 #endif
1679
1680     if (!(vp = frame_queue_peek_writable(&is->pictq)))
1681         return -1;
1682
1683     vp->sar = src_frame->sample_aspect_ratio;
1684     vp->uploaded = 0;
1685
1686     vp->width = src_frame->width;
1687     vp->height = src_frame->height;
1688     vp->format = src_frame->format;
1689
1690     vp->pts = pts;
1691     vp->duration = duration;
1692     vp->pos = pos;
1693     vp->serial = serial;
1694
1695     set_default_window_size(vp->width, vp->height, vp->sar);
1696
1697     av_frame_move_ref(vp->frame, src_frame);
1698     frame_queue_push(&is->pictq);
1699     return 0;
1700 }
1701
1702 static int get_video_frame(VideoState *is, AVFrame *frame)
1703 {
1704     int got_picture;
1705
1706     if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1707         return -1;
1708
1709     if (got_picture) {
1710         double dpts = NAN;
1711
1712         if (frame->pts != AV_NOPTS_VALUE)
1713             dpts = av_q2d(is->video_st->time_base) * frame->pts;
1714
1715         frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1716
1717         if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1718             if (frame->pts != AV_NOPTS_VALUE) {
1719                 double diff = dpts - get_master_clock(is);
1720                 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1721                     diff - is->frame_last_filter_delay < 0 &&
1722                     is->viddec.pkt_serial == is->vidclk.serial &&
1723                     is->videoq.nb_packets) {
1724                     is->frame_drops_early++;
1725                     av_frame_unref(frame);
1726                     got_picture = 0;
1727                 }
1728             }
1729         }
1730     }
1731
1732     return got_picture;
1733 }
1734
1735 #if CONFIG_AVFILTER
1736 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1737                                  AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1738 {
1739     int ret, i;
1740     int nb_filters = graph->nb_filters;
1741     AVFilterInOut *outputs = NULL, *inputs = NULL;
1742
1743     if (filtergraph) {
1744         outputs = avfilter_inout_alloc();
1745         inputs  = avfilter_inout_alloc();
1746         if (!outputs || !inputs) {
1747             ret = AVERROR(ENOMEM);
1748             goto fail;
1749         }
1750
1751         outputs->name       = av_strdup("in");
1752         outputs->filter_ctx = source_ctx;
1753         outputs->pad_idx    = 0;
1754         outputs->next       = NULL;
1755
1756         inputs->name        = av_strdup("out");
1757         inputs->filter_ctx  = sink_ctx;
1758         inputs->pad_idx     = 0;
1759         inputs->next        = NULL;
1760
1761         if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1762             goto fail;
1763     } else {
1764         if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1765             goto fail;
1766     }
1767
1768     /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1769     for (i = 0; i < graph->nb_filters - nb_filters; i++)
1770         FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1771
1772     ret = avfilter_graph_config(graph, NULL);
1773 fail:
1774     avfilter_inout_free(&outputs);
1775     avfilter_inout_free(&inputs);
1776     return ret;
1777 }
1778
1779 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1780 {
1781     static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1782     char sws_flags_str[512] = "";
1783     char buffersrc_args[256];
1784     int ret;
1785     AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1786     AVCodecParameters *codecpar = is->video_st->codecpar;
1787     AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1788     AVDictionaryEntry *e = NULL;
1789
1790     while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1791         if (!strcmp(e->key, "sws_flags")) {
1792             av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1793         } else
1794             av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1795     }
1796     if (strlen(sws_flags_str))
1797         sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1798
1799     graph->scale_sws_opts = av_strdup(sws_flags_str);
1800
1801     snprintf(buffersrc_args, sizeof(buffersrc_args),
1802              "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1803              frame->width, frame->height, frame->format,
1804              is->video_st->time_base.num, is->video_st->time_base.den,
1805              codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1806     if (fr.num && fr.den)
1807         av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1808
1809     if ((ret = avfilter_graph_create_filter(&filt_src,
1810                                             avfilter_get_by_name("buffer"),
1811                                             "ffplay_buffer", buffersrc_args, NULL,
1812                                             graph)) < 0)
1813         goto fail;
1814
1815     ret = avfilter_graph_create_filter(&filt_out,
1816                                        avfilter_get_by_name("buffersink"),
1817                                        "ffplay_buffersink", NULL, NULL, graph);
1818     if (ret < 0)
1819         goto fail;
1820
1821     if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts,  AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1822         goto fail;
1823
1824     last_filter = filt_out;
1825
1826 /* Note: this macro adds a filter before the lastly added filter, so the
1827  * processing order of the filters is in reverse */
1828 #define INSERT_FILT(name, arg) do {                                          \
1829     AVFilterContext *filt_ctx;                                               \
1830                                                                              \
1831     ret = avfilter_graph_create_filter(&filt_ctx,                            \
1832                                        avfilter_get_by_name(name),           \
1833                                        "ffplay_" name, arg, NULL, graph);    \
1834     if (ret < 0)                                                             \
1835         goto fail;                                                           \
1836                                                                              \
1837     ret = avfilter_link(filt_ctx, 0, last_filter, 0);                        \
1838     if (ret < 0)                                                             \
1839         goto fail;                                                           \
1840                                                                              \
1841     last_filter = filt_ctx;                                                  \
1842 } while (0)
1843
1844     if (autorotate) {
1845         double theta  = get_rotation(is->video_st);
1846
1847         if (fabs(theta - 90) < 1.0) {
1848             INSERT_FILT("transpose", "clock");
1849         } else if (fabs(theta - 180) < 1.0) {
1850             INSERT_FILT("hflip", NULL);
1851             INSERT_FILT("vflip", NULL);
1852         } else if (fabs(theta - 270) < 1.0) {
1853             INSERT_FILT("transpose", "cclock");
1854         } else if (fabs(theta) > 1.0) {
1855             char rotate_buf[64];
1856             snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1857             INSERT_FILT("rotate", rotate_buf);
1858         }
1859     }
1860
1861     if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1862         goto fail;
1863
1864     is->in_video_filter  = filt_src;
1865     is->out_video_filter = filt_out;
1866
1867 fail:
1868     return ret;
1869 }
1870
1871 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1872 {
1873     static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1874     int sample_rates[2] = { 0, -1 };
1875     int64_t channel_layouts[2] = { 0, -1 };
1876     int channels[2] = { 0, -1 };
1877     AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1878     char aresample_swr_opts[512] = "";
1879     AVDictionaryEntry *e = NULL;
1880     char asrc_args[256];
1881     int ret;
1882
1883     avfilter_graph_free(&is->agraph);
1884     if (!(is->agraph = avfilter_graph_alloc()))
1885         return AVERROR(ENOMEM);
1886
1887     while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1888         av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1889     if (strlen(aresample_swr_opts))
1890         aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1891     av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1892
1893     ret = snprintf(asrc_args, sizeof(asrc_args),
1894                    "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1895                    is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1896                    is->audio_filter_src.channels,
1897                    1, is->audio_filter_src.freq);
1898     if (is->audio_filter_src.channel_layout)
1899         snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1900                  ":channel_layout=0x%"PRIx64,  is->audio_filter_src.channel_layout);
1901
1902     ret = avfilter_graph_create_filter(&filt_asrc,
1903                                        avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1904                                        asrc_args, NULL, is->agraph);
1905     if (ret < 0)
1906         goto end;
1907
1908
1909     ret = avfilter_graph_create_filter(&filt_asink,
1910                                        avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1911                                        NULL, NULL, is->agraph);
1912     if (ret < 0)
1913         goto end;
1914
1915     if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts,  AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1916         goto end;
1917     if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1918         goto end;
1919
1920     if (force_output_format) {
1921         channel_layouts[0] = is->audio_tgt.channel_layout;
1922         channels       [0] = is->audio_tgt.channels;
1923         sample_rates   [0] = is->audio_tgt.freq;
1924         if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1925             goto end;
1926         if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1927             goto end;
1928         if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels       ,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1929             goto end;
1930         if ((ret = av_opt_set_int_list(filt_asink, "sample_rates"   , sample_rates   ,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1931             goto end;
1932     }
1933
1934
1935     if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1936         goto end;
1937
1938     is->in_audio_filter  = filt_asrc;
1939     is->out_audio_filter = filt_asink;
1940
1941 end:
1942     if (ret < 0)
1943         avfilter_graph_free(&is->agraph);
1944     return ret;
1945 }
1946 #endif  /* CONFIG_AVFILTER */
1947
1948 static int audio_thread(void *arg)
1949 {
1950     VideoState *is = arg;
1951     AVFrame *frame = av_frame_alloc();
1952     Frame *af;
1953 #if CONFIG_AVFILTER
1954     int last_serial = -1;
1955     int64_t dec_channel_layout;
1956     int reconfigure;
1957 #endif
1958     int got_frame = 0;
1959     AVRational tb;
1960     int ret = 0;
1961
1962     if (!frame)
1963         return AVERROR(ENOMEM);
1964
1965     do {
1966         if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1967             goto the_end;
1968
1969         if (got_frame) {
1970                 tb = (AVRational){1, frame->sample_rate};
1971
1972 #if CONFIG_AVFILTER
1973                 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
1974
1975                 reconfigure =
1976                     cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
1977                                    frame->format, av_frame_get_channels(frame))    ||
1978                     is->audio_filter_src.channel_layout != dec_channel_layout ||
1979                     is->audio_filter_src.freq           != frame->sample_rate ||
1980                     is->auddec.pkt_serial               != last_serial;
1981
1982                 if (reconfigure) {
1983                     char buf1[1024], buf2[1024];
1984                     av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
1985                     av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
1986                     av_log(NULL, AV_LOG_DEBUG,
1987                            "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
1988                            is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
1989                            frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
1990
1991                     is->audio_filter_src.fmt            = frame->format;
1992                     is->audio_filter_src.channels       = av_frame_get_channels(frame);
1993                     is->audio_filter_src.channel_layout = dec_channel_layout;
1994                     is->audio_filter_src.freq           = frame->sample_rate;
1995                     last_serial                         = is->auddec.pkt_serial;
1996
1997                     if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
1998                         goto the_end;
1999                 }
2000
2001             if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2002                 goto the_end;
2003
2004             while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2005                 tb = av_buffersink_get_time_base(is->out_audio_filter);
2006 #endif
2007                 if (!(af = frame_queue_peek_writable(&is->sampq)))
2008                     goto the_end;
2009
2010                 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2011                 af->pos = av_frame_get_pkt_pos(frame);
2012                 af->serial = is->auddec.pkt_serial;
2013                 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2014
2015                 av_frame_move_ref(af->frame, frame);
2016                 frame_queue_push(&is->sampq);
2017
2018 #if CONFIG_AVFILTER
2019                 if (is->audioq.serial != is->auddec.pkt_serial)
2020                     break;
2021             }
2022             if (ret == AVERROR_EOF)
2023                 is->auddec.finished = is->auddec.pkt_serial;
2024 #endif
2025         }
2026     } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2027  the_end:
2028 #if CONFIG_AVFILTER
2029     avfilter_graph_free(&is->agraph);
2030 #endif
2031     av_frame_free(&frame);
2032     return ret;
2033 }
2034
2035 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2036 {
2037     packet_queue_start(d->queue);
2038     d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2039     if (!d->decoder_tid) {
2040         av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2041         return AVERROR(ENOMEM);
2042     }
2043     return 0;
2044 }
2045
2046 static int video_thread(void *arg)
2047 {
2048     VideoState *is = arg;
2049     AVFrame *frame = av_frame_alloc();
2050     double pts;
2051     double duration;
2052     int ret;
2053     AVRational tb = is->video_st->time_base;
2054     AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2055
2056 #if CONFIG_AVFILTER
2057     AVFilterGraph *graph = avfilter_graph_alloc();
2058     AVFilterContext *filt_out = NULL, *filt_in = NULL;
2059     int last_w = 0;
2060     int last_h = 0;
2061     enum AVPixelFormat last_format = -2;
2062     int last_serial = -1;
2063     int last_vfilter_idx = 0;
2064     if (!graph) {
2065         av_frame_free(&frame);
2066         return AVERROR(ENOMEM);
2067     }
2068
2069 #endif
2070
2071     if (!frame) {
2072 #if CONFIG_AVFILTER
2073         avfilter_graph_free(&graph);
2074 #endif
2075         return AVERROR(ENOMEM);
2076     }
2077
2078     for (;;) {
2079         ret = get_video_frame(is, frame);
2080         if (ret < 0)
2081             goto the_end;
2082         if (!ret)
2083             continue;
2084
2085 #if CONFIG_AVFILTER
2086         if (   last_w != frame->width
2087             || last_h != frame->height
2088             || last_format != frame->format
2089             || last_serial != is->viddec.pkt_serial
2090             || last_vfilter_idx != is->vfilter_idx) {
2091             av_log(NULL, AV_LOG_DEBUG,
2092                    "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2093                    last_w, last_h,
2094                    (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2095                    frame->width, frame->height,
2096                    (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2097             avfilter_graph_free(&graph);
2098             graph = avfilter_graph_alloc();
2099             if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2100                 SDL_Event event;
2101                 event.type = FF_QUIT_EVENT;
2102                 event.user.data1 = is;
2103                 SDL_PushEvent(&event);
2104                 goto the_end;
2105             }
2106             filt_in  = is->in_video_filter;
2107             filt_out = is->out_video_filter;
2108             last_w = frame->width;
2109             last_h = frame->height;
2110             last_format = frame->format;
2111             last_serial = is->viddec.pkt_serial;
2112             last_vfilter_idx = is->vfilter_idx;
2113             frame_rate = av_buffersink_get_frame_rate(filt_out);
2114         }
2115
2116         ret = av_buffersrc_add_frame(filt_in, frame);
2117         if (ret < 0)
2118             goto the_end;
2119
2120         while (ret >= 0) {
2121             is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2122
2123             ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2124             if (ret < 0) {
2125                 if (ret == AVERROR_EOF)
2126                     is->viddec.finished = is->viddec.pkt_serial;
2127                 ret = 0;
2128                 break;
2129             }
2130
2131             is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2132             if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2133                 is->frame_last_filter_delay = 0;
2134             tb = av_buffersink_get_time_base(filt_out);
2135 #endif
2136             duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2137             pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2138             ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2139             av_frame_unref(frame);
2140 #if CONFIG_AVFILTER
2141         }
2142 #endif
2143
2144         if (ret < 0)
2145             goto the_end;
2146     }
2147  the_end:
2148 #if CONFIG_AVFILTER
2149     avfilter_graph_free(&graph);
2150 #endif
2151     av_frame_free(&frame);
2152     return 0;
2153 }
2154
2155 static int subtitle_thread(void *arg)
2156 {
2157     VideoState *is = arg;
2158     Frame *sp;
2159     int got_subtitle;
2160     double pts;
2161
2162     for (;;) {
2163         if (!(sp = frame_queue_peek_writable(&is->subpq)))
2164             return 0;
2165
2166         if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2167             break;
2168
2169         pts = 0;
2170
2171         if (got_subtitle && sp->sub.format == 0) {
2172             if (sp->sub.pts != AV_NOPTS_VALUE)
2173                 pts = sp->sub.pts / (double)AV_TIME_BASE;
2174             sp->pts = pts;
2175             sp->serial = is->subdec.pkt_serial;
2176             sp->width = is->subdec.avctx->width;
2177             sp->height = is->subdec.avctx->height;
2178             sp->uploaded = 0;
2179
2180             /* now we can update the picture count */
2181             frame_queue_push(&is->subpq);
2182         } else if (got_subtitle) {
2183             avsubtitle_free(&sp->sub);
2184         }
2185     }
2186     return 0;
2187 }
2188
2189 /* copy samples for viewing in editor window */
2190 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2191 {
2192     int size, len;
2193
2194     size = samples_size / sizeof(short);
2195     while (size > 0) {
2196         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2197         if (len > size)
2198             len = size;
2199         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2200         samples += len;
2201         is->sample_array_index += len;
2202         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2203             is->sample_array_index = 0;
2204         size -= len;
2205     }
2206 }
2207
2208 /* return the wanted number of samples to get better sync if sync_type is video
2209  * or external master clock */
2210 static int synchronize_audio(VideoState *is, int nb_samples)
2211 {
2212     int wanted_nb_samples = nb_samples;
2213
2214     /* if not master, then we try to remove or add samples to correct the clock */
2215     if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2216         double diff, avg_diff;
2217         int min_nb_samples, max_nb_samples;
2218
2219         diff = get_clock(&is->audclk) - get_master_clock(is);
2220
2221         if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2222             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2223             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2224                 /* not enough measures to have a correct estimate */
2225                 is->audio_diff_avg_count++;
2226             } else {
2227                 /* estimate the A-V difference */
2228                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2229
2230                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2231                     wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2232                     min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2233                     max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2234                     wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2235                 }
2236                 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2237                         diff, avg_diff, wanted_nb_samples - nb_samples,
2238                         is->audio_clock, is->audio_diff_threshold);
2239             }
2240         } else {
2241             /* too big difference : may be initial PTS errors, so
2242                reset A-V filter */
2243             is->audio_diff_avg_count = 0;
2244             is->audio_diff_cum       = 0;
2245         }
2246     }
2247
2248     return wanted_nb_samples;
2249 }
2250
2251 /**
2252  * Decode one audio frame and return its uncompressed size.
2253  *
2254  * The processed audio frame is decoded, converted if required, and
2255  * stored in is->audio_buf, with size in bytes given by the return
2256  * value.
2257  */
2258 static int audio_decode_frame(VideoState *is)
2259 {
2260     int data_size, resampled_data_size;
2261     int64_t dec_channel_layout;
2262     av_unused double audio_clock0;
2263     int wanted_nb_samples;
2264     Frame *af;
2265
2266     if (is->paused)
2267         return -1;
2268
2269     do {
2270 #if defined(_WIN32)
2271         while (frame_queue_nb_remaining(&is->sampq) == 0) {
2272             if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2273                 return -1;
2274             av_usleep (1000);
2275         }
2276 #endif
2277         if (!(af = frame_queue_peek_readable(&is->sampq)))
2278             return -1;
2279         frame_queue_next(&is->sampq);
2280     } while (af->serial != is->audioq.serial);
2281
2282     data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2283                                            af->frame->nb_samples,
2284                                            af->frame->format, 1);
2285
2286     dec_channel_layout =
2287         (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2288         af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2289     wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2290
2291     if (af->frame->format        != is->audio_src.fmt            ||
2292         dec_channel_layout       != is->audio_src.channel_layout ||
2293         af->frame->sample_rate   != is->audio_src.freq           ||
2294         (wanted_nb_samples       != af->frame->nb_samples && !is->swr_ctx)) {
2295         swr_free(&is->swr_ctx);
2296         is->swr_ctx = swr_alloc_set_opts(NULL,
2297                                          is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2298                                          dec_channel_layout,           af->frame->format, af->frame->sample_rate,
2299                                          0, NULL);
2300         if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2301             av_log(NULL, AV_LOG_ERROR,
2302                    "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2303                     af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2304                     is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2305             swr_free(&is->swr_ctx);
2306             return -1;
2307         }
2308         is->audio_src.channel_layout = dec_channel_layout;
2309         is->audio_src.channels       = av_frame_get_channels(af->frame);
2310         is->audio_src.freq = af->frame->sample_rate;
2311         is->audio_src.fmt = af->frame->format;
2312     }
2313
2314     if (is->swr_ctx) {
2315         const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2316         uint8_t **out = &is->audio_buf1;
2317         int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2318         int out_size  = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2319         int len2;
2320         if (out_size < 0) {
2321             av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2322             return -1;
2323         }
2324         if (wanted_nb_samples != af->frame->nb_samples) {
2325             if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2326                                         wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2327                 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2328                 return -1;
2329             }
2330         }
2331         av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2332         if (!is->audio_buf1)
2333             return AVERROR(ENOMEM);
2334         len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2335         if (len2 < 0) {
2336             av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2337             return -1;
2338         }
2339         if (len2 == out_count) {
2340             av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2341             if (swr_init(is->swr_ctx) < 0)
2342                 swr_free(&is->swr_ctx);
2343         }
2344         is->audio_buf = is->audio_buf1;
2345         resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2346     } else {
2347         is->audio_buf = af->frame->data[0];
2348         resampled_data_size = data_size;
2349     }
2350
2351     audio_clock0 = is->audio_clock;
2352     /* update the audio clock with the pts */
2353     if (!isnan(af->pts))
2354         is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2355     else
2356         is->audio_clock = NAN;
2357     is->audio_clock_serial = af->serial;
2358 #ifdef DEBUG
2359     {
2360         static double last_clock;
2361         printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2362                is->audio_clock - last_clock,
2363                is->audio_clock, audio_clock0);
2364         last_clock = is->audio_clock;
2365     }
2366 #endif
2367     return resampled_data_size;
2368 }
2369
2370 /* prepare a new audio buffer */
2371 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2372 {
2373     VideoState *is = opaque;
2374     int audio_size, len1;
2375
2376     audio_callback_time = av_gettime_relative();
2377
2378     while (len > 0) {
2379         if (is->audio_buf_index >= is->audio_buf_size) {
2380            audio_size = audio_decode_frame(is);
2381            if (audio_size < 0) {
2382                 /* if error, just output silence */
2383                is->audio_buf = NULL;
2384                is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2385            } else {
2386                if (is->show_mode != SHOW_MODE_VIDEO)
2387                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2388                is->audio_buf_size = audio_size;
2389            }
2390            is->audio_buf_index = 0;
2391         }
2392         len1 = is->audio_buf_size - is->audio_buf_index;
2393         if (len1 > len)
2394             len1 = len;
2395         if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2396             memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2397         else {
2398             memset(stream, 0, len1);
2399             if (!is->muted && is->audio_buf)
2400                 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2401         }
2402         len -= len1;
2403         stream += len1;
2404         is->audio_buf_index += len1;
2405     }
2406     is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2407     /* Let's assume the audio driver that is used by SDL has two periods. */
2408     if (!isnan(is->audio_clock)) {
2409         set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
2410         sync_clock_to_slave(&is->extclk, &is->audclk);
2411     }
2412 }
2413
2414 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2415 {
2416     SDL_AudioSpec wanted_spec, spec;
2417     const char *env;
2418     static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2419     static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2420     int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2421
2422     env = SDL_getenv("SDL_AUDIO_CHANNELS");
2423     if (env) {
2424         wanted_nb_channels = atoi(env);
2425         wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2426     }
2427     if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2428         wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2429         wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2430     }
2431     wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2432     wanted_spec.channels = wanted_nb_channels;
2433     wanted_spec.freq = wanted_sample_rate;
2434     if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2435         av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2436         return -1;
2437     }
2438     while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2439         next_sample_rate_idx--;
2440     wanted_spec.format = AUDIO_S16SYS;
2441     wanted_spec.silence = 0;
2442     wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2443     wanted_spec.callback = sdl_audio_callback;
2444     wanted_spec.userdata = opaque;
2445     while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2446         av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2447                wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2448         wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2449         if (!wanted_spec.channels) {
2450             wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2451             wanted_spec.channels = wanted_nb_channels;
2452             if (!wanted_spec.freq) {
2453                 av_log(NULL, AV_LOG_ERROR,
2454                        "No more combinations to try, audio open failed\n");
2455                 return -1;
2456             }
2457         }
2458         wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2459     }
2460     if (spec.format != AUDIO_S16SYS) {
2461         av_log(NULL, AV_LOG_ERROR,
2462                "SDL advised audio format %d is not supported!\n", spec.format);
2463         return -1;
2464     }
2465     if (spec.channels != wanted_spec.channels) {
2466         wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2467         if (!wanted_channel_layout) {
2468             av_log(NULL, AV_LOG_ERROR,
2469                    "SDL advised channel count %d is not supported!\n", spec.channels);
2470             return -1;
2471         }
2472     }
2473
2474     audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2475     audio_hw_params->freq = spec.freq;
2476     audio_hw_params->channel_layout = wanted_channel_layout;
2477     audio_hw_params->channels =  spec.channels;
2478     audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2479     audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
2480     if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2481         av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2482         return -1;
2483     }
2484     return spec.size;
2485 }
2486
2487 /* open a given stream. Return 0 if OK */
2488 static int stream_component_open(VideoState *is, int stream_index)
2489 {
2490     AVFormatContext *ic = is->ic;
2491     AVCodecContext *avctx;
2492     AVCodec *codec;
2493     const char *forced_codec_name = NULL;
2494     AVDictionary *opts = NULL;
2495     AVDictionaryEntry *t = NULL;
2496     int sample_rate, nb_channels;
2497     int64_t channel_layout;
2498     int ret = 0;
2499     int stream_lowres = lowres;
2500
2501     if (stream_index < 0 || stream_index >= ic->nb_streams)
2502         return -1;
2503
2504     avctx = avcodec_alloc_context3(NULL);
2505     if (!avctx)
2506         return AVERROR(ENOMEM);
2507
2508     ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2509     if (ret < 0)
2510         goto fail;
2511     av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2512
2513     codec = avcodec_find_decoder(avctx->codec_id);
2514
2515     switch(avctx->codec_type){
2516         case AVMEDIA_TYPE_AUDIO   : is->last_audio_stream    = stream_index; forced_codec_name =    audio_codec_name; break;
2517         case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2518         case AVMEDIA_TYPE_VIDEO   : is->last_video_stream    = stream_index; forced_codec_name =    video_codec_name; break;
2519     }
2520     if (forced_codec_name)
2521         codec = avcodec_find_decoder_by_name(forced_codec_name);
2522     if (!codec) {
2523         if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2524                                       "No codec could be found with name '%s'\n", forced_codec_name);
2525         else                   av_log(NULL, AV_LOG_WARNING,
2526                                       "No codec could be found with id %d\n", avctx->codec_id);
2527         ret = AVERROR(EINVAL);
2528         goto fail;
2529     }
2530
2531     avctx->codec_id = codec->id;
2532     if(stream_lowres > av_codec_get_max_lowres(codec)){
2533         av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2534                 av_codec_get_max_lowres(codec));
2535         stream_lowres = av_codec_get_max_lowres(codec);
2536     }
2537     av_codec_set_lowres(avctx, stream_lowres);
2538
2539 #if FF_API_EMU_EDGE
2540     if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2541 #endif
2542     if (fast)
2543         avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2544 #if FF_API_EMU_EDGE
2545     if(codec->capabilities & AV_CODEC_CAP_DR1)
2546         avctx->flags |= CODEC_FLAG_EMU_EDGE;
2547 #endif
2548
2549     opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2550     if (!av_dict_get(opts, "threads", NULL, 0))
2551         av_dict_set(&opts, "threads", "auto", 0);
2552     if (stream_lowres)
2553         av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2554     if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2555         av_dict_set(&opts, "refcounted_frames", "1", 0);
2556     if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2557         goto fail;
2558     }
2559     if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2560         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2561         ret =  AVERROR_OPTION_NOT_FOUND;
2562         goto fail;
2563     }
2564
2565     is->eof = 0;
2566     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2567     switch (avctx->codec_type) {
2568     case AVMEDIA_TYPE_AUDIO:
2569 #if CONFIG_AVFILTER
2570         {
2571             AVFilterContext *sink;
2572
2573             is->audio_filter_src.freq           = avctx->sample_rate;
2574             is->audio_filter_src.channels       = avctx->channels;
2575             is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2576             is->audio_filter_src.fmt            = avctx->sample_fmt;
2577             if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2578                 goto fail;
2579             sink = is->out_audio_filter;
2580             sample_rate    = av_buffersink_get_sample_rate(sink);
2581             nb_channels    = av_buffersink_get_channels(sink);
2582             channel_layout = av_buffersink_get_channel_layout(sink);
2583         }
2584 #else
2585         sample_rate    = avctx->sample_rate;
2586         nb_channels    = avctx->channels;
2587         channel_layout = avctx->channel_layout;
2588 #endif
2589
2590         /* prepare audio output */
2591         if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2592             goto fail;
2593         is->audio_hw_buf_size = ret;
2594         is->audio_src = is->audio_tgt;
2595         is->audio_buf_size  = 0;
2596         is->audio_buf_index = 0;
2597
2598         /* init averaging filter */
2599         is->audio_diff_avg_coef  = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2600         is->audio_diff_avg_count = 0;
2601         /* since we do not have a precise anough audio FIFO fullness,
2602            we correct audio sync only if larger than this threshold */
2603         is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2604
2605         is->audio_stream = stream_index;
2606         is->audio_st = ic->streams[stream_index];
2607
2608         decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2609         if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2610             is->auddec.start_pts = is->audio_st->start_time;
2611             is->auddec.start_pts_tb = is->audio_st->time_base;
2612         }
2613         if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2614             goto out;
2615         SDL_PauseAudio(0);
2616         break;
2617     case AVMEDIA_TYPE_VIDEO:
2618         is->video_stream = stream_index;
2619         is->video_st = ic->streams[stream_index];
2620
2621         decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2622         if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2623             goto out;
2624         is->queue_attachments_req = 1;
2625         break;
2626     case AVMEDIA_TYPE_SUBTITLE:
2627         is->subtitle_stream = stream_index;
2628         is->subtitle_st = ic->streams[stream_index];
2629
2630         decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2631         if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2632             goto out;
2633         break;
2634     default:
2635         break;
2636     }
2637     goto out;
2638
2639 fail:
2640     avcodec_free_context(&avctx);
2641 out:
2642     av_dict_free(&opts);
2643
2644     return ret;
2645 }
2646
2647 static int decode_interrupt_cb(void *ctx)
2648 {
2649     VideoState *is = ctx;
2650     return is->abort_request;
2651 }
2652
2653 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2654     return stream_id < 0 ||
2655            queue->abort_request ||
2656            (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2657            queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2658 }
2659
2660 static int is_realtime(AVFormatContext *s)
2661 {
2662     if(   !strcmp(s->iformat->name, "rtp")
2663        || !strcmp(s->iformat->name, "rtsp")
2664        || !strcmp(s->iformat->name, "sdp")
2665     )
2666         return 1;
2667
2668     if(s->pb && (   !strncmp(s->filename, "rtp:", 4)
2669                  || !strncmp(s->filename, "udp:", 4)
2670                 )
2671     )
2672         return 1;
2673     return 0;
2674 }
2675
2676 /* this thread gets the stream from the disk or the network */
2677 static int read_thread(void *arg)
2678 {
2679     VideoState *is = arg;
2680     AVFormatContext *ic = NULL;
2681     int err, i, ret;
2682     int st_index[AVMEDIA_TYPE_NB];
2683     AVPacket pkt1, *pkt = &pkt1;
2684     int64_t stream_start_time;
2685     int pkt_in_play_range = 0;
2686     AVDictionaryEntry *t;
2687     AVDictionary **opts;
2688     int orig_nb_streams;
2689     SDL_mutex *wait_mutex = SDL_CreateMutex();
2690     int scan_all_pmts_set = 0;
2691     int64_t pkt_ts;
2692
2693     if (!wait_mutex) {
2694         av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2695         ret = AVERROR(ENOMEM);
2696         goto fail;
2697     }
2698
2699     memset(st_index, -1, sizeof(st_index));
2700     is->last_video_stream = is->video_stream = -1;
2701     is->last_audio_stream = is->audio_stream = -1;
2702     is->last_subtitle_stream = is->subtitle_stream = -1;
2703     is->eof = 0;
2704
2705     ic = avformat_alloc_context();
2706     if (!ic) {
2707         av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2708         ret = AVERROR(ENOMEM);
2709         goto fail;
2710     }
2711     ic->interrupt_callback.callback = decode_interrupt_cb;
2712     ic->interrupt_callback.opaque = is;
2713     if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2714         av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2715         scan_all_pmts_set = 1;
2716     }
2717     err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2718     if (err < 0) {
2719         print_error(is->filename, err);
2720         ret = -1;
2721         goto fail;
2722     }
2723     if (scan_all_pmts_set)
2724         av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2725
2726     if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2727         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2728         ret = AVERROR_OPTION_NOT_FOUND;
2729         goto fail;
2730     }
2731     is->ic = ic;
2732
2733     if (genpts)
2734         ic->flags |= AVFMT_FLAG_GENPTS;
2735
2736     av_format_inject_global_side_data(ic);
2737
2738     opts = setup_find_stream_info_opts(ic, codec_opts);
2739     orig_nb_streams = ic->nb_streams;
2740
2741     err = avformat_find_stream_info(ic, opts);
2742
2743     for (i = 0; i < orig_nb_streams; i++)
2744         av_dict_free(&opts[i]);
2745     av_freep(&opts);
2746
2747     if (err < 0) {
2748         av_log(NULL, AV_LOG_WARNING,
2749                "%s: could not find codec parameters\n", is->filename);
2750         ret = -1;
2751         goto fail;
2752     }
2753
2754     if (ic->pb)
2755         ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2756
2757     if (seek_by_bytes < 0)
2758         seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2759
2760     is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2761
2762     if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2763         window_title = av_asprintf("%s - %s", t->value, input_filename);
2764
2765     /* if seeking requested, we execute it */
2766     if (start_time != AV_NOPTS_VALUE) {
2767         int64_t timestamp;
2768
2769         timestamp = start_time;
2770         /* add the stream start time */
2771         if (ic->start_time != AV_NOPTS_VALUE)
2772             timestamp += ic->start_time;
2773         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2774         if (ret < 0) {
2775             av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2776                     is->filename, (double)timestamp / AV_TIME_BASE);
2777         }
2778     }
2779
2780     is->realtime = is_realtime(ic);
2781
2782     if (show_status)
2783         av_dump_format(ic, 0, is->filename, 0);
2784
2785     for (i = 0; i < ic->nb_streams; i++) {
2786         AVStream *st = ic->streams[i];
2787         enum AVMediaType type = st->codecpar->codec_type;
2788         st->discard = AVDISCARD_ALL;
2789         if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2790             if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2791                 st_index[type] = i;
2792     }
2793     for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2794         if (wanted_stream_spec[i] && st_index[i] == -1) {
2795             av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i));
2796             st_index[i] = INT_MAX;
2797         }
2798     }
2799
2800     if (!video_disable)
2801         st_index[AVMEDIA_TYPE_VIDEO] =
2802             av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2803                                 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2804     if (!audio_disable)
2805         st_index[AVMEDIA_TYPE_AUDIO] =
2806             av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2807                                 st_index[AVMEDIA_TYPE_AUDIO],
2808                                 st_index[AVMEDIA_TYPE_VIDEO],
2809                                 NULL, 0);
2810     if (!video_disable && !subtitle_disable)
2811         st_index[AVMEDIA_TYPE_SUBTITLE] =
2812             av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2813                                 st_index[AVMEDIA_TYPE_SUBTITLE],
2814                                 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2815                                  st_index[AVMEDIA_TYPE_AUDIO] :
2816                                  st_index[AVMEDIA_TYPE_VIDEO]),
2817                                 NULL, 0);
2818
2819     is->show_mode = show_mode;
2820     if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2821         AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2822         AVCodecParameters *codecpar = st->codecpar;
2823         AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2824         if (codecpar->width)
2825             set_default_window_size(codecpar->width, codecpar->height, sar);
2826     }
2827
2828     /* open the streams */
2829     if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2830         stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2831     }
2832
2833     ret = -1;
2834     if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2835         ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2836     }
2837     if (is->show_mode == SHOW_MODE_NONE)
2838         is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2839
2840     if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2841         stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2842     }
2843
2844     if (is->video_stream < 0 && is->audio_stream < 0) {
2845         av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2846                is->filename);
2847         ret = -1;
2848         goto fail;
2849     }
2850
2851     if (infinite_buffer < 0 && is->realtime)
2852         infinite_buffer = 1;
2853
2854     for (;;) {
2855         if (is->abort_request)
2856             break;
2857         if (is->paused != is->last_paused) {
2858             is->last_paused = is->paused;
2859             if (is->paused)
2860                 is->read_pause_return = av_read_pause(ic);
2861             else
2862                 av_read_play(ic);
2863         }
2864 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2865         if (is->paused &&
2866                 (!strcmp(ic->iformat->name, "rtsp") ||
2867                  (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2868             /* wait 10 ms to avoid trying to get another packet */
2869             /* XXX: horrible */
2870             SDL_Delay(10);
2871             continue;
2872         }
2873 #endif
2874         if (is->seek_req) {
2875             int64_t seek_target = is->seek_pos;
2876             int64_t seek_min    = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2877             int64_t seek_max    = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2878 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2879 //      of the seek_pos/seek_rel variables
2880
2881             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2882             if (ret < 0) {
2883                 av_log(NULL, AV_LOG_ERROR,
2884                        "%s: error while seeking\n", is->ic->filename);
2885             } else {
2886                 if (is->audio_stream >= 0) {
2887                     packet_queue_flush(&is->audioq);
2888                     packet_queue_put(&is->audioq, &flush_pkt);
2889                 }
2890                 if (is->subtitle_stream >= 0) {
2891                     packet_queue_flush(&is->subtitleq);
2892                     packet_queue_put(&is->subtitleq, &flush_pkt);
2893                 }
2894                 if (is->video_stream >= 0) {
2895                     packet_queue_flush(&is->videoq);
2896                     packet_queue_put(&is->videoq, &flush_pkt);
2897                 }
2898                 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2899                    set_clock(&is->extclk, NAN, 0);
2900                 } else {
2901                    set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2902                 }
2903             }
2904             is->seek_req = 0;
2905             is->queue_attachments_req = 1;
2906             is->eof = 0;
2907             if (is->paused)
2908                 step_to_next_frame(is);
2909         }
2910         if (is->queue_attachments_req) {
2911             if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2912                 AVPacket copy;
2913                 if ((ret = av_copy_packet(&copy, &is->video_st->attached_pic)) < 0)
2914                     goto fail;
2915                 packet_queue_put(&is->videoq, &copy);
2916                 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2917             }
2918             is->queue_attachments_req = 0;
2919         }
2920
2921         /* if the queue are full, no need to read more */
2922         if (infinite_buffer<1 &&
2923               (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2924             || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2925                 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2926                 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2927             /* wait 10 ms */
2928             SDL_LockMutex(wait_mutex);
2929             SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2930             SDL_UnlockMutex(wait_mutex);
2931             continue;
2932         }
2933         if (!is->paused &&
2934             (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2935             (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2936             if (loop != 1 && (!loop || --loop)) {
2937                 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2938             } else if (autoexit) {
2939                 ret = AVERROR_EOF;
2940                 goto fail;
2941             }
2942         }
2943         ret = av_read_frame(ic, pkt);
2944         if (ret < 0) {
2945             if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
2946                 if (is->video_stream >= 0)
2947                     packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2948                 if (is->audio_stream >= 0)
2949                     packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2950                 if (is->subtitle_stream >= 0)
2951                     packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
2952                 is->eof = 1;
2953             }
2954             if (ic->pb && ic->pb->error)
2955                 break;
2956             SDL_LockMutex(wait_mutex);
2957             SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2958             SDL_UnlockMutex(wait_mutex);
2959             continue;
2960         } else {
2961             is->eof = 0;
2962         }
2963         /* check if packet is in play range specified by user, then queue, otherwise discard */
2964         stream_start_time = ic->streams[pkt->stream_index]->start_time;
2965         pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
2966         pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2967                 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
2968                 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2969                 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2970                 <= ((double)duration / 1000000);
2971         if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2972             packet_queue_put(&is->audioq, pkt);
2973         } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2974                    && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
2975             packet_queue_put(&is->videoq, pkt);
2976         } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2977             packet_queue_put(&is->subtitleq, pkt);
2978         } else {
2979             av_packet_unref(pkt);
2980         }
2981     }
2982
2983     ret = 0;
2984  fail:
2985     if (ic && !is->ic)
2986         avformat_close_input(&ic);
2987
2988     if (ret != 0) {
2989         SDL_Event event;
2990
2991         event.type = FF_QUIT_EVENT;
2992         event.user.data1 = is;
2993         SDL_PushEvent(&event);
2994     }
2995     SDL_DestroyMutex(wait_mutex);
2996     return 0;
2997 }
2998
2999 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3000 {
3001     VideoState *is;
3002
3003     is = av_mallocz(sizeof(VideoState));
3004     if (!is)
3005         return NULL;
3006     is->filename = av_strdup(filename);
3007     if (!is->filename)
3008         goto fail;
3009     is->iformat = iformat;
3010     is->ytop    = 0;
3011     is->xleft   = 0;
3012
3013     /* start video display */
3014     if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3015         goto fail;
3016     if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3017         goto fail;
3018     if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3019         goto fail;
3020
3021     if (packet_queue_init(&is->videoq) < 0 ||
3022         packet_queue_init(&is->audioq) < 0 ||
3023         packet_queue_init(&is->subtitleq) < 0)
3024         goto fail;
3025
3026     if (!(is->continue_read_thread = SDL_CreateCond())) {
3027         av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3028         goto fail;
3029     }
3030
3031     init_clock(&is->vidclk, &is->videoq.serial);
3032     init_clock(&is->audclk, &is->audioq.serial);
3033     init_clock(&is->extclk, &is->extclk.serial);
3034     is->audio_clock_serial = -1;
3035     if (startup_volume < 0)
3036         av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3037     if (startup_volume > 100)
3038         av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3039     startup_volume = av_clip(startup_volume, 0, 100);
3040     startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3041     is->audio_volume = startup_volume;
3042     is->muted = 0;
3043     is->av_sync_type = av_sync_type;
3044     is->read_tid     = SDL_CreateThread(read_thread, "read_thread", is);
3045     if (!is->read_tid) {
3046         av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3047 fail:
3048         stream_close(is);
3049         return NULL;
3050     }
3051     return is;
3052 }
3053
3054 static void stream_cycle_channel(VideoState *is, int codec_type)
3055 {
3056     AVFormatContext *ic = is->ic;
3057     int start_index, stream_index;
3058     int old_index;
3059     AVStream *st;
3060     AVProgram *p = NULL;
3061     int nb_streams = is->ic->nb_streams;
3062
3063     if (codec_type == AVMEDIA_TYPE_VIDEO) {
3064         start_index = is->last_video_stream;
3065         old_index = is->video_stream;
3066     } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3067         start_index = is->last_audio_stream;
3068         old_index = is->audio_stream;
3069     } else {
3070         start_index = is->last_subtitle_stream;
3071         old_index = is->subtitle_stream;
3072     }
3073     stream_index = start_index;
3074
3075     if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3076         p = av_find_program_from_stream(ic, NULL, is->video_stream);
3077         if (p) {
3078             nb_streams = p->nb_stream_indexes;
3079             for (start_index = 0; start_index < nb_streams; start_index++)
3080                 if (p->stream_index[start_index] == stream_index)
3081                     break;
3082             if (start_index == nb_streams)
3083                 start_index = -1;
3084             stream_index = start_index;
3085         }
3086     }
3087
3088     for (;;) {
3089         if (++stream_index >= nb_streams)
3090         {
3091             if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3092             {
3093                 stream_index = -1;
3094                 is->last_subtitle_stream = -1;
3095                 goto the_end;
3096             }
3097             if (start_index == -1)
3098                 return;
3099             stream_index = 0;
3100         }
3101         if (stream_index == start_index)
3102             return;
3103         st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3104         if (st->codecpar->codec_type == codec_type) {
3105             /* check that parameters are OK */
3106             switch (codec_type) {
3107             case AVMEDIA_TYPE_AUDIO:
3108                 if (st->codecpar->sample_rate != 0 &&
3109                     st->codecpar->channels != 0)
3110                     goto the_end;
3111                 break;
3112             case AVMEDIA_TYPE_VIDEO:
3113             case AVMEDIA_TYPE_SUBTITLE:
3114                 goto the_end;
3115             default:
3116                 break;
3117             }
3118         }
3119     }
3120  the_end:
3121     if (p && stream_index != -1)
3122         stream_index = p->stream_index[stream_index];
3123     av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3124            av_get_media_type_string(codec_type),
3125            old_index,
3126            stream_index);
3127
3128     stream_component_close(is, old_index);
3129     stream_component_open(is, stream_index);
3130 }
3131
3132
3133 static void toggle_full_screen(VideoState *is)
3134 {
3135     is_full_screen = !is_full_screen;
3136     SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3137 }
3138
3139 static void toggle_audio_display(VideoState *is)
3140 {
3141     int next = is->show_mode;
3142     do {
3143         next = (next + 1) % SHOW_MODE_NB;
3144     } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3145     if (is->show_mode != next) {
3146         is->force_refresh = 1;
3147         is->show_mode = next;
3148     }
3149 }
3150
3151 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3152     double remaining_time = 0.0;
3153     SDL_PumpEvents();
3154     while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3155         if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3156             SDL_ShowCursor(0);
3157             cursor_hidden = 1;
3158         }
3159         if (remaining_time > 0.0)
3160             av_usleep((int64_t)(remaining_time * 1000000.0));
3161         remaining_time = REFRESH_RATE;
3162         if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3163             video_refresh(is, &remaining_time);
3164         SDL_PumpEvents();
3165     }
3166 }
3167
3168 static void seek_chapter(VideoState *is, int incr)
3169 {
3170     int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3171     int i;
3172
3173     if (!is->ic->nb_chapters)
3174         return;
3175
3176     /* find the current chapter */
3177     for (i = 0; i < is->ic->nb_chapters; i++) {
3178         AVChapter *ch = is->ic->chapters[i];
3179         if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3180             i--;
3181             break;
3182         }
3183     }
3184
3185     i += incr;
3186     i = FFMAX(i, 0);
3187     if (i >= is->ic->nb_chapters)
3188         return;
3189
3190     av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3191     stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3192                                  AV_TIME_BASE_Q), 0, 0);
3193 }
3194
3195 /* handle an event sent by the GUI */
3196 static void event_loop(VideoState *cur_stream)
3197 {
3198     SDL_Event event;
3199     double incr, pos, frac;
3200
3201     for (;;) {
3202         double x;
3203         refresh_loop_wait_event(cur_stream, &event);
3204         switch (event.type) {
3205         case SDL_KEYDOWN:
3206             if (exit_on_keydown) {
3207                 do_exit(cur_stream);
3208                 break;
3209             }
3210             switch (event.key.keysym.sym) {
3211             case SDLK_ESCAPE:
3212             case SDLK_q:
3213                 do_exit(cur_stream);
3214                 break;
3215             case SDLK_f:
3216                 toggle_full_screen(cur_stream);
3217                 cur_stream->force_refresh = 1;
3218                 break;
3219             case SDLK_p:
3220             case SDLK_SPACE:
3221                 toggle_pause(cur_stream);
3222                 break;
3223             case SDLK_m:
3224                 toggle_mute(cur_stream);
3225                 break;
3226             case SDLK_KP_MULTIPLY:
3227             case SDLK_0:
3228                 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3229                 break;
3230             case SDLK_KP_DIVIDE:
3231             case SDLK_9:
3232                 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3233                 break;
3234             case SDLK_s: // S: Step to next frame
3235                 step_to_next_frame(cur_stream);
3236                 break;
3237             case SDLK_a:
3238                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3239                 break;
3240             case SDLK_v:
3241                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3242                 break;
3243             case SDLK_c:
3244                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3245                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3246                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3247                 break;
3248             case SDLK_t:
3249                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3250                 break;
3251             case SDLK_w:
3252 #if CONFIG_AVFILTER
3253                 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3254                     if (++cur_stream->vfilter_idx >= nb_vfilters)
3255                         cur_stream->vfilter_idx = 0;
3256                 } else {
3257                     cur_stream->vfilter_idx = 0;
3258                     toggle_audio_display(cur_stream);
3259                 }
3260 #else
3261                 toggle_audio_display(cur_stream);
3262 #endif
3263                 break;
3264             case SDLK_PAGEUP:
3265                 if (cur_stream->ic->nb_chapters <= 1) {
3266                     incr = 600.0;
3267                     goto do_seek;
3268                 }
3269                 seek_chapter(cur_stream, 1);
3270                 break;
3271             case SDLK_PAGEDOWN:
3272                 if (cur_stream->ic->nb_chapters <= 1) {
3273                     incr = -600.0;
3274                     goto do_seek;
3275                 }
3276                 seek_chapter(cur_stream, -1);
3277                 break;
3278             case SDLK_LEFT:
3279                 incr = -10.0;
3280                 goto do_seek;
3281             case SDLK_RIGHT:
3282                 incr = 10.0;
3283                 goto do_seek;
3284             case SDLK_UP:
3285                 incr = 60.0;
3286                 goto do_seek;
3287             case SDLK_DOWN:
3288                 incr = -60.0;
3289             do_seek:
3290                     if (seek_by_bytes) {
3291                         pos = -1;
3292                         if (pos < 0 && cur_stream->video_stream >= 0)
3293                             pos = frame_queue_last_pos(&cur_stream->pictq);
3294                         if (pos < 0 && cur_stream->audio_stream >= 0)
3295                             pos = frame_queue_last_pos(&cur_stream->sampq);
3296                         if (pos < 0)
3297                             pos = avio_tell(cur_stream->ic->pb);
3298                         if (cur_stream->ic->bit_rate)
3299                             incr *= cur_stream->ic->bit_rate / 8.0;
3300                         else
3301                             incr *= 180000.0;
3302                         pos += incr;
3303                         stream_seek(cur_stream, pos, incr, 1);
3304                     } else {
3305                         pos = get_master_clock(cur_stream);
3306                         if (isnan(pos))
3307                             pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3308                         pos += incr;
3309                         if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3310                             pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3311                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3312                     }
3313                 break;
3314             default:
3315                 break;
3316             }
3317             break;
3318         case SDL_MOUSEBUTTONDOWN:
3319             if (exit_on_mousedown) {
3320                 do_exit(cur_stream);
3321                 break;
3322             }
3323             if (event.button.button == SDL_BUTTON_LEFT) {
3324                 static int64_t last_mouse_left_click = 0;
3325                 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3326                     toggle_full_screen(cur_stream);
3327                     cur_stream->force_refresh = 1;
3328                     last_mouse_left_click = 0;
3329                 } else {
3330                     last_mouse_left_click = av_gettime_relative();
3331                 }
3332             }
3333         case SDL_MOUSEMOTION:
3334             if (cursor_hidden) {
3335                 SDL_ShowCursor(1);
3336                 cursor_hidden = 0;
3337             }
3338             cursor_last_shown = av_gettime_relative();
3339             if (event.type == SDL_MOUSEBUTTONDOWN) {
3340                 if (event.button.button != SDL_BUTTON_RIGHT)
3341                     break;
3342                 x = event.button.x;
3343             } else {
3344                 if (!(event.motion.state & SDL_BUTTON_RMASK))
3345                     break;
3346                 x = event.motion.x;
3347             }
3348                 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3349                     uint64_t size =  avio_size(cur_stream->ic->pb);
3350                     stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3351                 } else {
3352                     int64_t ts;
3353                     int ns, hh, mm, ss;
3354                     int tns, thh, tmm, tss;
3355                     tns  = cur_stream->ic->duration / 1000000LL;
3356                     thh  = tns / 3600;
3357                     tmm  = (tns % 3600) / 60;
3358                     tss  = (tns % 60);
3359                     frac = x / cur_stream->width;
3360                     ns   = frac * tns;
3361                     hh   = ns / 3600;
3362                     mm   = (ns % 3600) / 60;
3363                     ss   = (ns % 60);
3364                     av_log(NULL, AV_LOG_INFO,
3365                            "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
3366                             hh, mm, ss, thh, tmm, tss);
3367                     ts = frac * cur_stream->ic->duration;
3368                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3369                         ts += cur_stream->ic->start_time;
3370                     stream_seek(cur_stream, ts, 0, 0);
3371                 }
3372             break;
3373         case SDL_WINDOWEVENT:
3374             switch (event.window.event) {
3375                 case SDL_WINDOWEVENT_RESIZED:
3376                     screen_width  = cur_stream->width  = event.window.data1;
3377                     screen_height = cur_stream->height = event.window.data2;
3378                     if (cur_stream->vis_texture) {
3379                         SDL_DestroyTexture(cur_stream->vis_texture);
3380                         cur_stream->vis_texture = NULL;
3381                     }
3382                 case SDL_WINDOWEVENT_EXPOSED:
3383                     cur_stream->force_refresh = 1;
3384             }
3385             break;
3386         case SDL_QUIT:
3387         case FF_QUIT_EVENT:
3388             do_exit(cur_stream);
3389             break;
3390         default:
3391             break;
3392         }
3393     }
3394 }
3395
3396 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3397 {
3398     av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3399     return opt_default(NULL, "video_size", arg);
3400 }
3401
3402 static int opt_width(void *optctx, const char *opt, const char *arg)
3403 {
3404     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3405     return 0;
3406 }
3407
3408 static int opt_height(void *optctx, const char *opt, const char *arg)
3409 {
3410     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3411     return 0;
3412 }
3413
3414 static int opt_format(void *optctx, const char *opt, const char *arg)
3415 {
3416     file_iformat = av_find_input_format(arg);
3417     if (!file_iformat) {
3418         av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3419         return AVERROR(EINVAL);
3420     }
3421     return 0;
3422 }
3423
3424 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3425 {
3426     av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3427     return opt_default(NULL, "pixel_format", arg);
3428 }
3429
3430 static int opt_sync(void *optctx, const char *opt, const char *arg)
3431 {
3432     if (!strcmp(arg, "audio"))
3433         av_sync_type = AV_SYNC_AUDIO_MASTER;
3434     else if (!strcmp(arg, "video"))
3435         av_sync_type = AV_SYNC_VIDEO_MASTER;
3436     else if (!strcmp(arg, "ext"))
3437         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3438     else {
3439         av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3440         exit(1);
3441     }
3442     return 0;
3443 }
3444
3445 static int opt_seek(void *optctx, const char *opt, const char *arg)
3446 {
3447     start_time = parse_time_or_die(opt, arg, 1);
3448     return 0;
3449 }
3450
3451 static int opt_duration(void *optctx, const char *opt, const char *arg)
3452 {
3453     duration = parse_time_or_die(opt, arg, 1);
3454     return 0;
3455 }
3456
3457 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3458 {
3459     show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3460                 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3461                 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT  :
3462                 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3463     return 0;
3464 }
3465
3466 static void opt_input_file(void *optctx, const char *filename)
3467 {
3468     if (input_filename) {
3469         av_log(NULL, AV_LOG_FATAL,
3470                "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3471                 filename, input_filename);
3472         exit(1);
3473     }
3474     if (!strcmp(filename, "-"))
3475         filename = "pipe:";
3476     input_filename = filename;
3477 }
3478
3479 static int opt_codec(void *optctx, const char *opt, const char *arg)
3480 {
3481    const char *spec = strchr(opt, ':');
3482    if (!spec) {
3483        av_log(NULL, AV_LOG_ERROR,
3484               "No media specifier was specified in '%s' in option '%s'\n",
3485                arg, opt);
3486        return AVERROR(EINVAL);
3487    }
3488    spec++;
3489    switch (spec[0]) {
3490    case 'a' :    audio_codec_name = arg; break;
3491    case 's' : subtitle_codec_name = arg; break;
3492    case 'v' :    video_codec_name = arg; break;
3493    default:
3494        av_log(NULL, AV_LOG_ERROR,
3495               "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3496        return AVERROR(EINVAL);
3497    }
3498    return 0;
3499 }
3500
3501 static int dummy;
3502
3503 static const OptionDef options[] = {
3504 #include "cmdutils_common_opts.h"
3505     { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3506     { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3507     { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3508     { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3509     { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3510     { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3511     { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3512     { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3513     { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3514     { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3515     { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3516     { "t", HAS_ARG, { .func_arg = opt_duration }, "play  \"duration\" seconds of audio/video", "duration" },
3517     { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3518     { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3519     { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3520     { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3521     { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3522     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3523     { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3524     { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3525     { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3526     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3527     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3528     { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3529     { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3530     { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3531     { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3532     { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3533     { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3534     { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3535     { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3536 #if CONFIG_AVFILTER
3537     { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3538     { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3539 #endif
3540     { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3541     { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3542     { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3543     { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3544     { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3545     { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {    &audio_codec_name }, "force audio decoder",    "decoder_name" },
3546     { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3547     { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {    &video_codec_name }, "force video decoder",    "decoder_name" },
3548     { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3549     { NULL, },
3550 };
3551
3552 static void show_usage(void)
3553 {
3554     av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3555     av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3556     av_log(NULL, AV_LOG_INFO, "\n");
3557 }
3558
3559 void show_help_default(const char *opt, const char *arg)
3560 {
3561     av_log_set_callback(log_callback_help);
3562     show_usage();
3563     show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3564     show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3565     printf("\n");
3566     show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3567     show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3568 #if !CONFIG_AVFILTER
3569     show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3570 #else
3571     show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3572 #endif
3573     printf("\nWhile playing:\n"
3574            "q, ESC              quit\n"
3575            "f                   toggle full screen\n"
3576            "p, SPC              pause\n"
3577            "m                   toggle mute\n"
3578            "9, 0                decrease and increase volume respectively\n"
3579            "/, *                decrease and increase volume respectively\n"
3580            "a                   cycle audio channel in the current program\n"
3581            "v                   cycle video channel\n"
3582            "t                   cycle subtitle channel in the current program\n"
3583            "c                   cycle program\n"
3584            "w                   cycle video filters or show modes\n"
3585            "s                   activate frame-step mode\n"
3586            "left/right          seek backward/forward 10 seconds\n"
3587            "down/up             seek backward/forward 1 minute\n"
3588            "page down/page up   seek backward/forward 10 minutes\n"
3589            "right mouse click   seek to percentage in file corresponding to fraction of width\n"
3590            "left double-click   toggle full screen\n"
3591            );
3592 }
3593
3594 static int lockmgr(void **mtx, enum AVLockOp op)
3595 {
3596    switch(op) {
3597       case AV_LOCK_CREATE:
3598           *mtx = SDL_CreateMutex();
3599           if(!*mtx) {
3600               av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3601               return 1;
3602           }
3603           return 0;
3604       case AV_LOCK_OBTAIN:
3605           return !!SDL_LockMutex(*mtx);
3606       case AV_LOCK_RELEASE:
3607           return !!SDL_UnlockMutex(*mtx);
3608       case AV_LOCK_DESTROY:
3609           SDL_DestroyMutex(*mtx);
3610           return 0;
3611    }
3612    return 1;
3613 }
3614
3615 /* Called from the main */
3616 int main(int argc, char **argv)
3617 {
3618     int flags;
3619     VideoState *is;
3620
3621     init_dynload();
3622
3623     av_log_set_flags(AV_LOG_SKIP_REPEATED);
3624     parse_loglevel(argc, argv, options);
3625
3626     /* register all codecs, demux and protocols */
3627 #if CONFIG_AVDEVICE
3628     avdevice_register_all();
3629 #endif
3630 #if CONFIG_AVFILTER
3631     avfilter_register_all();
3632 #endif
3633     av_register_all();
3634     avformat_network_init();
3635
3636     init_opts();
3637
3638     signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
3639     signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
3640
3641     show_banner(argc, argv, options);
3642
3643     parse_options(NULL, argc, argv, options, opt_input_file);
3644
3645     if (!input_filename) {
3646         show_usage();
3647         av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3648         av_log(NULL, AV_LOG_FATAL,
3649                "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3650         exit(1);
3651     }
3652
3653     if (display_disable) {
3654         video_disable = 1;
3655     }
3656     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3657     if (audio_disable)
3658         flags &= ~SDL_INIT_AUDIO;
3659     else {
3660         /* Try to work around an occasional ALSA buffer underflow issue when the
3661          * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3662         if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3663             SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3664     }
3665     if (display_disable)
3666         flags &= ~SDL_INIT_VIDEO;
3667     if (SDL_Init (flags)) {
3668         av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3669         av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3670         exit(1);
3671     }
3672
3673     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3674     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3675
3676     if (av_lockmgr_register(lockmgr)) {
3677         av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3678         do_exit(NULL);
3679     }
3680
3681     av_init_packet(&flush_pkt);
3682     flush_pkt.data = (uint8_t *)&flush_pkt;
3683
3684     is = stream_open(input_filename, file_iformat);
3685     if (!is) {
3686         av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");
3687         do_exit(NULL);
3688     }
3689
3690     event_loop(is);
3691
3692     /* never returns */
3693
3694     return 0;
3695 }