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