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