FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffplay.c
Date: 2025-10-11 06:18:21
Exec Total Coverage
Lines: 0 2225 0.0%
Functions: 0 100 0.0%
Branches: 0 1510 0.0%

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