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