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