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