• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
65 const char program_name[] = "ffplay";
66 const 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 
112 static unsigned sws_flags = SWS_BICUBIC;
113 
114 typedef struct MyAVPacketList {
115     AVPacket *pkt;
116     int serial;
117 } MyAVPacketList;
118 
119 typedef 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 
135 typedef 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 
143 typedef struct Clock {
144     double pts;           /* clock base */
145     double pts_drift;     /* clock base minus time at which we updated the clock */
146     double last_updated;
147     double speed;
148     int serial;           /* clock is based on a packet with this serial */
149     int paused;
150     int *queue_serial;    /* pointer to the current packet queue serial, used for obsolete clock detection */
151 } Clock;
152 
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
155     AVFrame *frame;
156     AVSubtitle sub;
157     int serial;
158     double pts;           /* presentation timestamp for the frame */
159     double duration;      /* estimated duration of the frame */
160     int64_t pos;          /* byte position of the frame in the input file */
161     int width;
162     int height;
163     int format;
164     AVRational sar;
165     int uploaded;
166     int flip_v;
167 } Frame;
168 
169 typedef struct FrameQueue {
170     Frame queue[FRAME_QUEUE_SIZE];
171     int rindex;
172     int windex;
173     int size;
174     int max_size;
175     int keep_last;
176     int rindex_shown;
177     SDL_mutex *mutex;
178     SDL_cond *cond;
179     PacketQueue *pktq;
180 } FrameQueue;
181 
182 enum {
183     AV_SYNC_AUDIO_MASTER, /* default choice */
184     AV_SYNC_VIDEO_MASTER,
185     AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
186 };
187 
188 typedef struct Decoder {
189     AVPacket *pkt;
190     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 
203 typedef 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 */
310 static const AVInputFormat *file_iformat;
311 static const char *input_filename;
312 static const char *window_title;
313 static int default_width  = 640;
314 static int default_height = 480;
315 static int screen_width  = 0;
316 static int screen_height = 0;
317 static int screen_left = SDL_WINDOWPOS_CENTERED;
318 static int screen_top = SDL_WINDOWPOS_CENTERED;
319 static int audio_disable;
320 static int video_disable;
321 static int subtitle_disable;
322 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
323 static int seek_by_bytes = -1;
324 static float seek_interval = 10;
325 static int display_disable;
326 static int borderless;
327 static int alwaysontop;
328 static int startup_volume = 100;
329 static int show_status = -1;
330 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
331 static int64_t start_time = AV_NOPTS_VALUE;
332 static int64_t duration = AV_NOPTS_VALUE;
333 static int fast = 0;
334 static int genpts = 0;
335 static int lowres = 0;
336 static int decoder_reorder_pts = -1;
337 static int autoexit;
338 static int exit_on_keydown;
339 static int exit_on_mousedown;
340 static int loop = 1;
341 static int framedrop = -1;
342 static int infinite_buffer = -1;
343 static enum ShowMode show_mode = SHOW_MODE_NONE;
344 static const char *audio_codec_name;
345 static const char *subtitle_codec_name;
346 static const char *video_codec_name;
347 double rdftspeed = 0.02;
348 static int64_t cursor_last_shown;
349 static int cursor_hidden = 0;
350 #if CONFIG_AVFILTER
351 static const char **vfilters_list = NULL;
352 static int nb_vfilters = 0;
353 static char *afilters = NULL;
354 #endif
355 static int autorotate = 1;
356 static int find_stream_info = 1;
357 static int filter_nbthreads = 0;
358 
359 /* current context */
360 static int is_full_screen;
361 static int64_t audio_callback_time;
362 
363 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
364 
365 static SDL_Window *window;
366 static SDL_Renderer *renderer;
367 static SDL_RendererInfo renderer_info = {0};
368 static SDL_AudioDeviceID audio_dev;
369 
370 static 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
opt_add_vfilter(void * optctx,const char * opt,const char * arg)397 static 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 
405 static inline
cmp_audio_fmts(enum AVSampleFormat fmt1,int64_t channel_count1,enum AVSampleFormat fmt2,int64_t channel_count2)406 int 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 
packet_queue_put_private(PacketQueue * q,AVPacket * pkt)416 static 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 
packet_queue_put(PacketQueue * q,AVPacket * pkt)439 static 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 
packet_queue_put_nullpacket(PacketQueue * q,AVPacket * pkt,int stream_index)461 static 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 */
packet_queue_init(PacketQueue * q)468 static 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 
packet_queue_flush(PacketQueue * q)488 static 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 
packet_queue_destroy(PacketQueue * q)502 static 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 
packet_queue_abort(PacketQueue * q)510 static 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 
packet_queue_start(PacketQueue * q)521 static 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.  */
packet_queue_get(PacketQueue * q,AVPacket * pkt,int block,int * serial)530 static 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 
decoder_init(Decoder * d,AVCodecContext * avctx,PacketQueue * queue,SDL_cond * empty_queue_cond)564 static 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 
decoder_decode_frame(Decoder * d,AVFrame * frame,AVSubtitle * sub)577 static 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 
decoder_destroy(Decoder * d)666 static void decoder_destroy(Decoder *d) {
667     av_packet_free(&d->pkt);
668     avcodec_free_context(&d->avctx);
669 }
670 
frame_queue_unref_item(Frame * vp)671 static void frame_queue_unref_item(Frame *vp)
672 {
673     av_frame_unref(vp->frame);
674     avsubtitle_free(&vp->sub);
675 }
676 
frame_queue_init(FrameQueue * f,PacketQueue * pktq,int max_size,int keep_last)677 static 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 
frame_queue_destory(FrameQueue * f)698 static 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 
frame_queue_signal(FrameQueue * f)710 static void frame_queue_signal(FrameQueue *f)
711 {
712     SDL_LockMutex(f->mutex);
713     SDL_CondSignal(f->cond);
714     SDL_UnlockMutex(f->mutex);
715 }
716 
frame_queue_peek(FrameQueue * f)717 static Frame *frame_queue_peek(FrameQueue *f)
718 {
719     return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
720 }
721 
frame_queue_peek_next(FrameQueue * f)722 static Frame *frame_queue_peek_next(FrameQueue *f)
723 {
724     return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
725 }
726 
frame_queue_peek_last(FrameQueue * f)727 static Frame *frame_queue_peek_last(FrameQueue *f)
728 {
729     return &f->queue[f->rindex];
730 }
731 
frame_queue_peek_writable(FrameQueue * f)732 static 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 
frame_queue_peek_readable(FrameQueue * f)748 static 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 
frame_queue_push(FrameQueue * f)764 static 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 
frame_queue_next(FrameQueue * f)774 static 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 */
frame_queue_nb_remaining(FrameQueue * f)790 static int frame_queue_nb_remaining(FrameQueue *f)
791 {
792     return f->size - f->rindex_shown;
793 }
794 
795 /* return last shown position */
frame_queue_last_pos(FrameQueue * f)796 static 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 
decoder_abort(Decoder * d,FrameQueue * fq)805 static 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 
fill_rectangle(int x,int y,int w,int h)814 static 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 
realloc_texture(SDL_Texture ** texture,Uint32 new_format,int new_width,int new_height,SDL_BlendMode blendmode,int init_texture)825 static 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 
calculate_display_rect(SDL_Rect * rect,int scr_xleft,int scr_ytop,int scr_width,int scr_height,int pic_width,int pic_height,AVRational pic_sar)849 static 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 
get_sdl_pix_fmt_and_blendmode(int format,Uint32 * sdl_pix_fmt,SDL_BlendMode * sdl_blendmode)876 static 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 
upload_texture(SDL_Texture ** tex,AVFrame * frame,struct SwsContext ** img_convert_ctx)894 static 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 
set_sdl_yuv_conversion_mode(AVFrame * frame)945 static 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 
video_image_display(VideoState * is)961 static 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 
compute_mod(int a,int b)1046 static inline int compute_mod(int a, int b)
1047 {
1048     return a < 0 ? a%b + b : a%b;
1049 }
1050 
video_audio_display(VideoState * s)1051 static 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 
stream_component_close(VideoState * is,int stream_index)1193 static 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 
stream_close(VideoState * is)1250 static 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 
do_exit(VideoState * is)1287 static 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 
sigterm_handler(int sig)1308 static void sigterm_handler(int sig)
1309 {
1310     exit(123);
1311 }
1312 
set_default_window_size(int width,int height,AVRational sar)1313 static 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 
video_open(VideoState * is)1325 static 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 */
video_display(VideoState * is)1349 static 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 
get_clock(Clock * c)1363 static 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 
set_clock_at(Clock * c,double pts,int serial,double time)1375 static 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 
set_clock(Clock * c,double pts,int serial)1383 static 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 
set_clock_speed(Clock * c,double speed)1389 static void set_clock_speed(Clock *c, double speed)
1390 {
1391     set_clock(c, get_clock(c), c->serial);
1392     c->speed = speed;
1393 }
1394 
init_clock(Clock * c,int * queue_serial)1395 static 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 
sync_clock_to_slave(Clock * c,Clock * slave)1403 static 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 
get_master_sync_type(VideoState * is)1411 static 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 */
get_master_clock(VideoState * is)1428 static 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 
check_external_clock_speed(VideoState * is)1446 static 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 */
stream_seek(VideoState * is,int64_t pos,int64_t rel,int by_bytes)1461 static 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 */
stream_toggle_pause(VideoState * is)1475 static 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 
toggle_pause(VideoState * is)1488 static void toggle_pause(VideoState *is)
1489 {
1490     stream_toggle_pause(is);
1491     is->step = 0;
1492 }
1493 
toggle_mute(VideoState * is)1494 static void toggle_mute(VideoState *is)
1495 {
1496     is->muted = !is->muted;
1497 }
1498 
update_volume(VideoState * is,int sign,double step)1499 static 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 
step_to_next_frame(VideoState * is)1506 static 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 
compute_target_delay(double delay,VideoState * is)1514 static 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 
vp_duration(VideoState * is,Frame * vp,Frame * nextvp)1544 static 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 
update_video_pts(VideoState * is,double pts,int64_t pos,int serial)1556 static 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 */
video_refresh(void * opaque,double * remaining_time)1563 static 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) {
1583 retry:
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         }
1674 display:
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 
queue_picture(VideoState * is,AVFrame * src_frame,double pts,double duration,int64_t pos,int serial)1732 static 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 
get_video_frame(VideoState * is,AVFrame * frame)1763 static 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
configure_filtergraph(AVFilterGraph * graph,const char * filtergraph,AVFilterContext * source_ctx,AVFilterContext * sink_ctx)1797 static 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);
1834 fail:
1835     avfilter_inout_free(&outputs);
1836     avfilter_inout_free(&inputs);
1837     return ret;
1838 }
1839 
configure_video_filters(AVFilterGraph * graph,VideoState * is,const char * vfilters,AVFrame * frame)1840 static 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 
1941 fail:
1942     return ret;
1943 }
1944 
configure_audio_filters(VideoState * is,const char * afilters,int force_output_format)1945 static 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 
2011 end:
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 
audio_thread(void * arg)2020 static 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 
decoder_start(Decoder * d,int (* fn)(void *),const char * thread_name,void * arg)2105 static 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 
video_thread(void * arg)2116 static 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 
subtitle_thread(void * arg)2223 static 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 */
update_sample_display(VideoState * is,short * samples,int samples_size)2258 static 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 */
synchronize_audio(VideoState * is,int nb_samples)2278 static 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  */
audio_decode_frame(VideoState * is)2326 static 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 */
sdl_audio_callback(void * opaque,Uint8 * stream,int len)2435 static 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 
audio_open(void * opaque,AVChannelLayout * wanted_channel_layout,int wanted_sample_rate,struct AudioParams * audio_hw_params)2478 static 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 */
stream_component_open(VideoState * is,int stream_index)2555 static 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 
2703 fail:
2704     avcodec_free_context(&avctx);
2705 out:
2706     av_channel_layout_uninit(&ch_layout);
2707     av_dict_free(&opts);
2708 
2709     return ret;
2710 }
2711 
decode_interrupt_cb(void * ctx)2712 static int decode_interrupt_cb(void *ctx)
2713 {
2714     VideoState *is = ctx;
2715     return is->abort_request;
2716 }
2717 
stream_has_enough_packets(AVStream * st,int stream_id,PacketQueue * queue)2718 static 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 
is_realtime(AVFormatContext * s)2725 static 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 */
read_thread(void * arg)2742 static 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 
stream_open(const char * filename,const AVInputFormat * iformat)3067 static 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());
3119 fail:
3120         stream_close(is);
3121         return NULL;
3122     }
3123     return is;
3124 }
3125 
stream_cycle_channel(VideoState * is,int codec_type)3126 static 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 
toggle_full_screen(VideoState * is)3205 static 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 
toggle_audio_display(VideoState * is)3211 static 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 
refresh_loop_wait_event(VideoState * is,SDL_Event * event)3223 static 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 
seek_chapter(VideoState * is,int incr)3240 static 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 */
event_loop(VideoState * cur_stream)3268 static 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 
opt_width(void * optctx,const char * opt,const char * arg)3467 static 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 
opt_height(void * optctx,const char * opt,const char * arg)3473 static 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 
opt_format(void * optctx,const char * opt,const char * arg)3479 static 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 
opt_sync(void * optctx,const char * opt,const char * arg)3489 static 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 
opt_seek(void * optctx,const char * opt,const char * arg)3504 static 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 
opt_duration(void * optctx,const char * opt,const char * arg)3510 static 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 
opt_show_mode(void * optctx,const char * opt,const char * arg)3516 static 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 
opt_input_file(void * optctx,const char * filename)3525 static 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 
opt_codec(void * optctx,const char * opt,const char * arg)3538 static 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 
3560 static int dummy;
3561 
3562 static 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 
show_usage(void)3615 static 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 
show_help_default(const char * opt,const char * arg)3622 void 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 */
main(int argc,char ** argv)3658 int 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