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