2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
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.
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.
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
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control in dB */
77 #define SDL_VOLUME_STEP (0.75)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
110 static unsigned sws_flags = SWS_BICUBIC;
112 typedef struct MyAVPacketList {
114 struct MyAVPacketList *next;
118 typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
134 typedef struct AudioParams {
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
143 typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
148 int serial; /* clock is based on a packet with this serial */
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
169 typedef struct FrameQueue {
170 Frame queue[FRAME_QUEUE_SIZE];
183 AV_SYNC_AUDIO_MASTER, /* default choice */
184 AV_SYNC_VIDEO_MASTER,
185 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
188 typedef struct Decoder {
191 AVCodecContext *avctx;
195 SDL_cond *empty_queue_cond;
197 AVRational start_pts_tb;
199 AVRational next_pts_tb;
200 SDL_Thread *decoder_tid;
203 typedef struct VideoState {
204 SDL_Thread *read_tid;
205 AVInputFormat *iformat;
210 int queue_attachments_req;
215 int read_pause_return;
236 int audio_clock_serial;
237 double audio_diff_cum; /* used for AV difference average computation */
238 double audio_diff_avg_coef;
239 double audio_diff_threshold;
240 int audio_diff_avg_count;
243 int audio_hw_buf_size;
246 unsigned int audio_buf_size; /* in bytes */
247 unsigned int audio_buf1_size;
248 int audio_buf_index; /* in bytes */
249 int audio_write_buf_size;
252 struct AudioParams audio_src;
254 struct AudioParams audio_filter_src;
256 struct AudioParams audio_tgt;
257 struct SwrContext *swr_ctx;
258 int frame_drops_early;
259 int frame_drops_late;
262 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
264 int16_t sample_array[SAMPLE_ARRAY_SIZE];
265 int sample_array_index;
269 FFTSample *rdft_data;
271 double last_vis_time;
272 SDL_Texture *vis_texture;
273 SDL_Texture *sub_texture;
274 SDL_Texture *vid_texture;
277 AVStream *subtitle_st;
278 PacketQueue subtitleq;
281 double frame_last_returned_time;
282 double frame_last_filter_delay;
286 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
287 struct SwsContext *img_convert_ctx;
288 struct SwsContext *sub_convert_ctx;
292 int width, height, xleft, ytop;
297 AVFilterContext *in_video_filter; // the first filter in the video chain
298 AVFilterContext *out_video_filter; // the last filter in the video chain
299 AVFilterContext *in_audio_filter; // the first filter in the audio chain
300 AVFilterContext *out_audio_filter; // the last filter in the audio chain
301 AVFilterGraph *agraph; // audio filter graph
304 int last_video_stream, last_audio_stream, last_subtitle_stream;
306 SDL_cond *continue_read_thread;
309 /* options specified by the user */
310 static AVInputFormat *file_iformat;
311 static const char *input_filename;
312 static const char *window_title;
313 static int default_width = 640;
314 static int default_height = 480;
315 static int screen_width = 0;
316 static int screen_height = 0;
317 static int screen_left = SDL_WINDOWPOS_CENTERED;
318 static int screen_top = SDL_WINDOWPOS_CENTERED;
319 static int audio_disable;
320 static int video_disable;
321 static int subtitle_disable;
322 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
323 static int seek_by_bytes = -1;
324 static float seek_interval = 10;
325 static int display_disable;
326 static int borderless;
327 static int alwaysontop;
328 static int startup_volume = 100;
329 static int show_status = 1;
330 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
331 static int64_t start_time = AV_NOPTS_VALUE;
332 static int64_t duration = AV_NOPTS_VALUE;
334 static int genpts = 0;
335 static int lowres = 0;
336 static int decoder_reorder_pts = -1;
338 static int exit_on_keydown;
339 static int exit_on_mousedown;
341 static int framedrop = -1;
342 static int infinite_buffer = -1;
343 static enum ShowMode show_mode = SHOW_MODE_NONE;
344 static const char *audio_codec_name;
345 static const char *subtitle_codec_name;
346 static const char *video_codec_name;
347 double rdftspeed = 0.02;
348 static int64_t cursor_last_shown;
349 static int cursor_hidden = 0;
351 static const char **vfilters_list = NULL;
352 static int nb_vfilters = 0;
353 static char *afilters = NULL;
355 static int autorotate = 1;
356 static int find_stream_info = 1;
357 static int filter_nbthreads = 0;
359 /* current context */
360 static int is_full_screen;
361 static int64_t audio_callback_time;
363 static AVPacket flush_pkt;
365 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
367 static SDL_Window *window;
368 static SDL_Renderer *renderer;
369 static SDL_RendererInfo renderer_info = {0};
370 static SDL_AudioDeviceID audio_dev;
372 static const struct TextureFormatEntry {
373 enum AVPixelFormat format;
375 } sdl_texture_format_map[] = {
376 { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 },
377 { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 },
378 { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 },
379 { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 },
380 { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 },
381 { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 },
382 { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 },
383 { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 },
384 { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 },
385 { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 },
386 { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 },
387 { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 },
388 { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 },
389 { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 },
390 { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 },
391 { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 },
392 { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV },
393 { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 },
394 { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY },
395 { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN },
399 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
401 GROW_ARRAY(vfilters_list, nb_vfilters);
402 vfilters_list[nb_vfilters - 1] = arg;
408 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
409 enum AVSampleFormat fmt2, int64_t channel_count2)
411 /* If channel count == 1, planar and non-planar formats are the same */
412 if (channel_count1 == 1 && channel_count2 == 1)
413 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
415 return channel_count1 != channel_count2 || fmt1 != fmt2;
419 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
421 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
422 return channel_layout;
427 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
429 MyAVPacketList *pkt1;
431 if (q->abort_request)
434 pkt1 = av_malloc(sizeof(MyAVPacketList));
439 if (pkt == &flush_pkt)
441 pkt1->serial = q->serial;
446 q->last_pkt->next = pkt1;
449 q->size += pkt1->pkt.size + sizeof(*pkt1);
450 q->duration += pkt1->pkt.duration;
451 /* XXX: should duplicate packet data in DV case */
452 SDL_CondSignal(q->cond);
456 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
460 SDL_LockMutex(q->mutex);
461 ret = packet_queue_put_private(q, pkt);
462 SDL_UnlockMutex(q->mutex);
464 if (pkt != &flush_pkt && ret < 0)
465 av_packet_unref(pkt);
470 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
472 AVPacket pkt1, *pkt = &pkt1;
476 pkt->stream_index = stream_index;
477 return packet_queue_put(q, pkt);
480 /* packet queue handling */
481 static int packet_queue_init(PacketQueue *q)
483 memset(q, 0, sizeof(PacketQueue));
484 q->mutex = SDL_CreateMutex();
486 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
487 return AVERROR(ENOMEM);
489 q->cond = SDL_CreateCond();
491 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
492 return AVERROR(ENOMEM);
494 q->abort_request = 1;
498 static void packet_queue_flush(PacketQueue *q)
500 MyAVPacketList *pkt, *pkt1;
502 SDL_LockMutex(q->mutex);
503 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
505 av_packet_unref(&pkt->pkt);
513 SDL_UnlockMutex(q->mutex);
516 static void packet_queue_destroy(PacketQueue *q)
518 packet_queue_flush(q);
519 SDL_DestroyMutex(q->mutex);
520 SDL_DestroyCond(q->cond);
523 static void packet_queue_abort(PacketQueue *q)
525 SDL_LockMutex(q->mutex);
527 q->abort_request = 1;
529 SDL_CondSignal(q->cond);
531 SDL_UnlockMutex(q->mutex);
534 static void packet_queue_start(PacketQueue *q)
536 SDL_LockMutex(q->mutex);
537 q->abort_request = 0;
538 packet_queue_put_private(q, &flush_pkt);
539 SDL_UnlockMutex(q->mutex);
542 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
543 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
545 MyAVPacketList *pkt1;
548 SDL_LockMutex(q->mutex);
551 if (q->abort_request) {
558 q->first_pkt = pkt1->next;
562 q->size -= pkt1->pkt.size + sizeof(*pkt1);
563 q->duration -= pkt1->pkt.duration;
566 *serial = pkt1->serial;
574 SDL_CondWait(q->cond, q->mutex);
577 SDL_UnlockMutex(q->mutex);
581 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
582 memset(d, 0, sizeof(Decoder));
585 d->empty_queue_cond = empty_queue_cond;
586 d->start_pts = AV_NOPTS_VALUE;
590 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
591 int ret = AVERROR(EAGAIN);
596 if (d->queue->serial == d->pkt_serial) {
598 if (d->queue->abort_request)
601 switch (d->avctx->codec_type) {
602 case AVMEDIA_TYPE_VIDEO:
603 ret = avcodec_receive_frame(d->avctx, frame);
605 if (decoder_reorder_pts == -1) {
606 frame->pts = frame->best_effort_timestamp;
607 } else if (!decoder_reorder_pts) {
608 frame->pts = frame->pkt_dts;
612 case AVMEDIA_TYPE_AUDIO:
613 ret = avcodec_receive_frame(d->avctx, frame);
615 AVRational tb = (AVRational){1, frame->sample_rate};
616 if (frame->pts != AV_NOPTS_VALUE)
617 frame->pts = av_rescale_q(frame->pts, d->avctx->pkt_timebase, tb);
618 else if (d->next_pts != AV_NOPTS_VALUE)
619 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
620 if (frame->pts != AV_NOPTS_VALUE) {
621 d->next_pts = frame->pts + frame->nb_samples;
627 if (ret == AVERROR_EOF) {
628 d->finished = d->pkt_serial;
629 avcodec_flush_buffers(d->avctx);
634 } while (ret != AVERROR(EAGAIN));
638 if (d->queue->nb_packets == 0)
639 SDL_CondSignal(d->empty_queue_cond);
640 if (d->packet_pending) {
641 av_packet_move_ref(&pkt, &d->pkt);
642 d->packet_pending = 0;
644 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
647 } while (d->queue->serial != d->pkt_serial);
649 if (pkt.data == flush_pkt.data) {
650 avcodec_flush_buffers(d->avctx);
652 d->next_pts = d->start_pts;
653 d->next_pts_tb = d->start_pts_tb;
655 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
657 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
659 ret = AVERROR(EAGAIN);
661 if (got_frame && !pkt.data) {
662 d->packet_pending = 1;
663 av_packet_move_ref(&d->pkt, &pkt);
665 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
668 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
669 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
670 d->packet_pending = 1;
671 av_packet_move_ref(&d->pkt, &pkt);
674 av_packet_unref(&pkt);
679 static void decoder_destroy(Decoder *d) {
680 av_packet_unref(&d->pkt);
681 avcodec_free_context(&d->avctx);
684 static void frame_queue_unref_item(Frame *vp)
686 av_frame_unref(vp->frame);
687 avsubtitle_free(&vp->sub);
690 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
693 memset(f, 0, sizeof(FrameQueue));
694 if (!(f->mutex = SDL_CreateMutex())) {
695 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
696 return AVERROR(ENOMEM);
698 if (!(f->cond = SDL_CreateCond())) {
699 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
700 return AVERROR(ENOMEM);
703 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
704 f->keep_last = !!keep_last;
705 for (i = 0; i < f->max_size; i++)
706 if (!(f->queue[i].frame = av_frame_alloc()))
707 return AVERROR(ENOMEM);
711 static void frame_queue_destory(FrameQueue *f)
714 for (i = 0; i < f->max_size; i++) {
715 Frame *vp = &f->queue[i];
716 frame_queue_unref_item(vp);
717 av_frame_free(&vp->frame);
719 SDL_DestroyMutex(f->mutex);
720 SDL_DestroyCond(f->cond);
723 static void frame_queue_signal(FrameQueue *f)
725 SDL_LockMutex(f->mutex);
726 SDL_CondSignal(f->cond);
727 SDL_UnlockMutex(f->mutex);
730 static Frame *frame_queue_peek(FrameQueue *f)
732 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
735 static Frame *frame_queue_peek_next(FrameQueue *f)
737 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
740 static Frame *frame_queue_peek_last(FrameQueue *f)
742 return &f->queue[f->rindex];
745 static Frame *frame_queue_peek_writable(FrameQueue *f)
747 /* wait until we have space to put a new frame */
748 SDL_LockMutex(f->mutex);
749 while (f->size >= f->max_size &&
750 !f->pktq->abort_request) {
751 SDL_CondWait(f->cond, f->mutex);
753 SDL_UnlockMutex(f->mutex);
755 if (f->pktq->abort_request)
758 return &f->queue[f->windex];
761 static Frame *frame_queue_peek_readable(FrameQueue *f)
763 /* wait until we have a readable a new frame */
764 SDL_LockMutex(f->mutex);
765 while (f->size - f->rindex_shown <= 0 &&
766 !f->pktq->abort_request) {
767 SDL_CondWait(f->cond, f->mutex);
769 SDL_UnlockMutex(f->mutex);
771 if (f->pktq->abort_request)
774 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
777 static void frame_queue_push(FrameQueue *f)
779 if (++f->windex == f->max_size)
781 SDL_LockMutex(f->mutex);
783 SDL_CondSignal(f->cond);
784 SDL_UnlockMutex(f->mutex);
787 static void frame_queue_next(FrameQueue *f)
789 if (f->keep_last && !f->rindex_shown) {
793 frame_queue_unref_item(&f->queue[f->rindex]);
794 if (++f->rindex == f->max_size)
796 SDL_LockMutex(f->mutex);
798 SDL_CondSignal(f->cond);
799 SDL_UnlockMutex(f->mutex);
802 /* return the number of undisplayed frames in the queue */
803 static int frame_queue_nb_remaining(FrameQueue *f)
805 return f->size - f->rindex_shown;
808 /* return last shown position */
809 static int64_t frame_queue_last_pos(FrameQueue *f)
811 Frame *fp = &f->queue[f->rindex];
812 if (f->rindex_shown && fp->serial == f->pktq->serial)
818 static void decoder_abort(Decoder *d, FrameQueue *fq)
820 packet_queue_abort(d->queue);
821 frame_queue_signal(fq);
822 SDL_WaitThread(d->decoder_tid, NULL);
823 d->decoder_tid = NULL;
824 packet_queue_flush(d->queue);
827 static inline void fill_rectangle(int x, int y, int w, int h)
835 SDL_RenderFillRect(renderer, &rect);
838 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
842 if (!*texture || SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
846 SDL_DestroyTexture(*texture);
847 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
849 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
852 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
854 memset(pixels, 0, pitch * new_height);
855 SDL_UnlockTexture(*texture);
857 av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
862 static void calculate_display_rect(SDL_Rect *rect,
863 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
864 int pic_width, int pic_height, AVRational pic_sar)
866 AVRational aspect_ratio = pic_sar;
867 int64_t width, height, x, y;
869 if (av_cmp_q(aspect_ratio, av_make_q(0, 1)) <= 0)
870 aspect_ratio = av_make_q(1, 1);
872 aspect_ratio = av_mul_q(aspect_ratio, av_make_q(pic_width, pic_height));
874 /* XXX: we suppose the screen has a 1.0 pixel ratio */
876 width = av_rescale(height, aspect_ratio.num, aspect_ratio.den) & ~1;
877 if (width > scr_width) {
879 height = av_rescale(width, aspect_ratio.den, aspect_ratio.num) & ~1;
881 x = (scr_width - width) / 2;
882 y = (scr_height - height) / 2;
883 rect->x = scr_xleft + x;
884 rect->y = scr_ytop + y;
885 rect->w = FFMAX((int)width, 1);
886 rect->h = FFMAX((int)height, 1);
889 static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
892 *sdl_blendmode = SDL_BLENDMODE_NONE;
893 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
894 if (format == AV_PIX_FMT_RGB32 ||
895 format == AV_PIX_FMT_RGB32_1 ||
896 format == AV_PIX_FMT_BGR32 ||
897 format == AV_PIX_FMT_BGR32_1)
898 *sdl_blendmode = SDL_BLENDMODE_BLEND;
899 for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
900 if (format == sdl_texture_format_map[i].format) {
901 *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
907 static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
910 SDL_BlendMode sdl_blendmode;
911 get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
912 if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
914 switch (sdl_pix_fmt) {
915 case SDL_PIXELFORMAT_UNKNOWN:
916 /* This should only happen if we are not using avfilter... */
917 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
918 frame->width, frame->height, frame->format, frame->width, frame->height,
919 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
920 if (*img_convert_ctx != NULL) {
923 if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
924 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
925 0, frame->height, pixels, pitch);
926 SDL_UnlockTexture(*tex);
929 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
933 case SDL_PIXELFORMAT_IYUV:
934 if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
935 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
936 frame->data[1], frame->linesize[1],
937 frame->data[2], frame->linesize[2]);
938 } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) {
939 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0],
940 frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
941 frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
943 av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
948 if (frame->linesize[0] < 0) {
949 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
951 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
958 static void set_sdl_yuv_conversion_mode(AVFrame *frame)
960 #if SDL_VERSION_ATLEAST(2,0,8)
961 SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
962 if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
963 if (frame->color_range == AVCOL_RANGE_JPEG)
964 mode = SDL_YUV_CONVERSION_JPEG;
965 else if (frame->colorspace == AVCOL_SPC_BT709)
966 mode = SDL_YUV_CONVERSION_BT709;
967 else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
968 mode = SDL_YUV_CONVERSION_BT601;
970 SDL_SetYUVConversionMode(mode);
974 static void video_image_display(VideoState *is)
980 vp = frame_queue_peek_last(&is->pictq);
981 if (is->subtitle_st) {
982 if (frame_queue_nb_remaining(&is->subpq) > 0) {
983 sp = frame_queue_peek(&is->subpq);
985 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
990 if (!sp->width || !sp->height) {
991 sp->width = vp->width;
992 sp->height = vp->height;
994 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
997 for (i = 0; i < sp->sub.num_rects; i++) {
998 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1000 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
1001 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
1002 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
1003 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
1005 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
1006 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
1007 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
1008 0, NULL, NULL, NULL);
1009 if (!is->sub_convert_ctx) {
1010 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1013 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
1014 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
1015 0, sub_rect->h, pixels, pitch);
1016 SDL_UnlockTexture(is->sub_texture);
1026 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1028 if (!vp->uploaded) {
1029 if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
1032 vp->flip_v = vp->frame->linesize[0] < 0;
1035 set_sdl_yuv_conversion_mode(vp->frame);
1036 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
1037 set_sdl_yuv_conversion_mode(NULL);
1039 #if USE_ONEPASS_SUBTITLE_RENDER
1040 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
1043 double xratio = (double)rect.w / (double)sp->width;
1044 double yratio = (double)rect.h / (double)sp->height;
1045 for (i = 0; i < sp->sub.num_rects; i++) {
1046 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
1047 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
1048 .y = rect.y + sub_rect->y * yratio,
1049 .w = sub_rect->w * xratio,
1050 .h = sub_rect->h * yratio};
1051 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
1057 static inline int compute_mod(int a, int b)
1059 return a < 0 ? a%b + b : a%b;
1062 static void video_audio_display(VideoState *s)
1064 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1065 int ch, channels, h, h2;
1067 int rdft_bits, nb_freq;
1069 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1071 nb_freq = 1 << (rdft_bits - 1);
1073 /* compute display index : center on currently output samples */
1074 channels = s->audio_tgt.channels;
1075 nb_display_channels = channels;
1077 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1079 delay = s->audio_write_buf_size;
1082 /* to be more precise, we take into account the time spent since
1083 the last buffer computation */
1084 if (audio_callback_time) {
1085 time_diff = av_gettime_relative() - audio_callback_time;
1086 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1089 delay += 2 * data_used;
1090 if (delay < data_used)
1093 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1094 if (s->show_mode == SHOW_MODE_WAVES) {
1096 for (i = 0; i < 1000; i += channels) {
1097 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1098 int a = s->sample_array[idx];
1099 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1100 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1101 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1103 if (h < score && (b ^ c) < 0) {
1110 s->last_i_start = i_start;
1112 i_start = s->last_i_start;
1115 if (s->show_mode == SHOW_MODE_WAVES) {
1116 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1118 /* total height for one channel */
1119 h = s->height / nb_display_channels;
1120 /* graph height / 2 */
1122 for (ch = 0; ch < nb_display_channels; ch++) {
1124 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1125 for (x = 0; x < s->width; x++) {
1126 y = (s->sample_array[i] * h2) >> 15;
1133 fill_rectangle(s->xleft + x, ys, 1, y);
1135 if (i >= SAMPLE_ARRAY_SIZE)
1136 i -= SAMPLE_ARRAY_SIZE;
1140 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1142 for (ch = 1; ch < nb_display_channels; ch++) {
1143 y = s->ytop + ch * h;
1144 fill_rectangle(s->xleft, y, s->width, 1);
1147 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1150 nb_display_channels= FFMIN(nb_display_channels, 2);
1151 if (rdft_bits != s->rdft_bits) {
1152 av_rdft_end(s->rdft);
1153 av_free(s->rdft_data);
1154 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1155 s->rdft_bits = rdft_bits;
1156 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1158 if (!s->rdft || !s->rdft_data){
1159 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1160 s->show_mode = SHOW_MODE_WAVES;
1163 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1166 for (ch = 0; ch < nb_display_channels; ch++) {
1167 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1169 for (x = 0; x < 2 * nb_freq; x++) {
1170 double w = (x-nb_freq) * (1.0 / nb_freq);
1171 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1173 if (i >= SAMPLE_ARRAY_SIZE)
1174 i -= SAMPLE_ARRAY_SIZE;
1176 av_rdft_calc(s->rdft, data[ch]);
1178 /* Least efficient way to do this, we should of course
1179 * directly access it but it is more than fast enough. */
1180 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1182 pixels += pitch * s->height;
1183 for (y = 0; y < s->height; y++) {
1184 double w = 1 / sqrt(nb_freq);
1185 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
1186 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1191 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1193 SDL_UnlockTexture(s->vis_texture);
1195 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1199 if (s->xpos >= s->width)
1204 static void stream_component_close(VideoState *is, int stream_index)
1206 AVFormatContext *ic = is->ic;
1207 AVCodecParameters *codecpar;
1209 if (stream_index < 0 || stream_index >= ic->nb_streams)
1211 codecpar = ic->streams[stream_index]->codecpar;
1213 switch (codecpar->codec_type) {
1214 case AVMEDIA_TYPE_AUDIO:
1215 decoder_abort(&is->auddec, &is->sampq);
1216 SDL_CloseAudioDevice(audio_dev);
1217 decoder_destroy(&is->auddec);
1218 swr_free(&is->swr_ctx);
1219 av_freep(&is->audio_buf1);
1220 is->audio_buf1_size = 0;
1221 is->audio_buf = NULL;
1224 av_rdft_end(is->rdft);
1225 av_freep(&is->rdft_data);
1230 case AVMEDIA_TYPE_VIDEO:
1231 decoder_abort(&is->viddec, &is->pictq);
1232 decoder_destroy(&is->viddec);
1234 case AVMEDIA_TYPE_SUBTITLE:
1235 decoder_abort(&is->subdec, &is->subpq);
1236 decoder_destroy(&is->subdec);
1242 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1243 switch (codecpar->codec_type) {
1244 case AVMEDIA_TYPE_AUDIO:
1245 is->audio_st = NULL;
1246 is->audio_stream = -1;
1248 case AVMEDIA_TYPE_VIDEO:
1249 is->video_st = NULL;
1250 is->video_stream = -1;
1252 case AVMEDIA_TYPE_SUBTITLE:
1253 is->subtitle_st = NULL;
1254 is->subtitle_stream = -1;
1261 static void stream_close(VideoState *is)
1263 /* XXX: use a special url_shutdown call to abort parse cleanly */
1264 is->abort_request = 1;
1265 SDL_WaitThread(is->read_tid, NULL);
1267 /* close each stream */
1268 if (is->audio_stream >= 0)
1269 stream_component_close(is, is->audio_stream);
1270 if (is->video_stream >= 0)
1271 stream_component_close(is, is->video_stream);
1272 if (is->subtitle_stream >= 0)
1273 stream_component_close(is, is->subtitle_stream);
1275 avformat_close_input(&is->ic);
1277 packet_queue_destroy(&is->videoq);
1278 packet_queue_destroy(&is->audioq);
1279 packet_queue_destroy(&is->subtitleq);
1281 /* free all pictures */
1282 frame_queue_destory(&is->pictq);
1283 frame_queue_destory(&is->sampq);
1284 frame_queue_destory(&is->subpq);
1285 SDL_DestroyCond(is->continue_read_thread);
1286 sws_freeContext(is->img_convert_ctx);
1287 sws_freeContext(is->sub_convert_ctx);
1288 av_free(is->filename);
1289 if (is->vis_texture)
1290 SDL_DestroyTexture(is->vis_texture);
1291 if (is->vid_texture)
1292 SDL_DestroyTexture(is->vid_texture);
1293 if (is->sub_texture)
1294 SDL_DestroyTexture(is->sub_texture);
1298 static void do_exit(VideoState *is)
1304 SDL_DestroyRenderer(renderer);
1306 SDL_DestroyWindow(window);
1309 av_freep(&vfilters_list);
1311 avformat_network_deinit();
1315 av_log(NULL, AV_LOG_QUIET, "%s", "");
1319 static void sigterm_handler(int sig)
1324 static void set_default_window_size(int width, int height, AVRational sar)
1327 int max_width = screen_width ? screen_width : INT_MAX;
1328 int max_height = screen_height ? screen_height : INT_MAX;
1329 if (max_width == INT_MAX && max_height == INT_MAX)
1330 max_height = height;
1331 calculate_display_rect(&rect, 0, 0, max_width, max_height, width, height, sar);
1332 default_width = rect.w;
1333 default_height = rect.h;
1336 static int video_open(VideoState *is)
1340 w = screen_width ? screen_width : default_width;
1341 h = screen_height ? screen_height : default_height;
1344 window_title = input_filename;
1345 SDL_SetWindowTitle(window, window_title);
1347 SDL_SetWindowSize(window, w, h);
1348 SDL_SetWindowPosition(window, screen_left, screen_top);
1350 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1351 SDL_ShowWindow(window);
1359 /* display the current picture, if any */
1360 static void video_display(VideoState *is)
1365 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1366 SDL_RenderClear(renderer);
1367 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1368 video_audio_display(is);
1369 else if (is->video_st)
1370 video_image_display(is);
1371 SDL_RenderPresent(renderer);
1374 static double get_clock(Clock *c)
1376 if (*c->queue_serial != c->serial)
1381 double time = av_gettime_relative() / 1000000.0;
1382 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1386 static void set_clock_at(Clock *c, double pts, int serial, double time)
1389 c->last_updated = time;
1390 c->pts_drift = c->pts - time;
1394 static void set_clock(Clock *c, double pts, int serial)
1396 double time = av_gettime_relative() / 1000000.0;
1397 set_clock_at(c, pts, serial, time);
1400 static void set_clock_speed(Clock *c, double speed)
1402 set_clock(c, get_clock(c), c->serial);
1406 static void init_clock(Clock *c, int *queue_serial)
1410 c->queue_serial = queue_serial;
1411 set_clock(c, NAN, -1);
1414 static void sync_clock_to_slave(Clock *c, Clock *slave)
1416 double clock = get_clock(c);
1417 double slave_clock = get_clock(slave);
1418 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1419 set_clock(c, slave_clock, slave->serial);
1422 static int get_master_sync_type(VideoState *is) {
1423 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1425 return AV_SYNC_VIDEO_MASTER;
1427 return AV_SYNC_AUDIO_MASTER;
1428 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1430 return AV_SYNC_AUDIO_MASTER;
1432 return AV_SYNC_EXTERNAL_CLOCK;
1434 return AV_SYNC_EXTERNAL_CLOCK;
1438 /* get the current master clock value */
1439 static double get_master_clock(VideoState *is)
1443 switch (get_master_sync_type(is)) {
1444 case AV_SYNC_VIDEO_MASTER:
1445 val = get_clock(&is->vidclk);
1447 case AV_SYNC_AUDIO_MASTER:
1448 val = get_clock(&is->audclk);
1451 val = get_clock(&is->extclk);
1457 static void check_external_clock_speed(VideoState *is) {
1458 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1459 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1460 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1461 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1462 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1463 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1465 double speed = is->extclk.speed;
1467 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1471 /* seek in the stream */
1472 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1474 if (!is->seek_req) {
1477 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1479 is->seek_flags |= AVSEEK_FLAG_BYTE;
1481 SDL_CondSignal(is->continue_read_thread);
1485 /* pause or resume the video */
1486 static void stream_toggle_pause(VideoState *is)
1489 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1490 if (is->read_pause_return != AVERROR(ENOSYS)) {
1491 is->vidclk.paused = 0;
1493 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1495 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1496 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1499 static void toggle_pause(VideoState *is)
1501 stream_toggle_pause(is);
1505 static void toggle_mute(VideoState *is)
1507 is->muted = !is->muted;
1510 static void update_volume(VideoState *is, int sign, double step)
1512 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1513 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1514 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1517 static void step_to_next_frame(VideoState *is)
1519 /* if the stream is paused unpause it, then step */
1521 stream_toggle_pause(is);
1525 static double compute_target_delay(double delay, VideoState *is)
1527 double sync_threshold, diff = 0;
1529 /* update delay to follow master synchronisation source */
1530 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1531 /* if video is slave, we try to correct big delays by
1532 duplicating or deleting a frame */
1533 diff = get_clock(&is->vidclk) - get_master_clock(is);
1535 /* skip or repeat frame. We take into account the
1536 delay to compute the threshold. I still don't know
1537 if it is the best guess */
1538 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1539 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1540 if (diff <= -sync_threshold)
1541 delay = FFMAX(0, delay + diff);
1542 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1543 delay = delay + diff;
1544 else if (diff >= sync_threshold)
1549 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1555 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1556 if (vp->serial == nextvp->serial) {
1557 double duration = nextvp->pts - vp->pts;
1558 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1559 return vp->duration;
1567 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1568 /* update current video pts */
1569 set_clock(&is->vidclk, pts, serial);
1570 sync_clock_to_slave(&is->extclk, &is->vidclk);
1573 /* called to display each frame */
1574 static void video_refresh(void *opaque, double *remaining_time)
1576 VideoState *is = opaque;
1581 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1582 check_external_clock_speed(is);
1584 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1585 time = av_gettime_relative() / 1000000.0;
1586 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1588 is->last_vis_time = time;
1590 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1595 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1596 // nothing to do, no picture to display in the queue
1598 double last_duration, duration, delay;
1601 /* dequeue the picture */
1602 lastvp = frame_queue_peek_last(&is->pictq);
1603 vp = frame_queue_peek(&is->pictq);
1605 if (vp->serial != is->videoq.serial) {
1606 frame_queue_next(&is->pictq);
1610 if (lastvp->serial != vp->serial)
1611 is->frame_timer = av_gettime_relative() / 1000000.0;
1616 /* compute nominal last_duration */
1617 last_duration = vp_duration(is, lastvp, vp);
1618 delay = compute_target_delay(last_duration, is);
1620 time= av_gettime_relative()/1000000.0;
1621 if (time < is->frame_timer + delay) {
1622 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1626 is->frame_timer += delay;
1627 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1628 is->frame_timer = time;
1630 SDL_LockMutex(is->pictq.mutex);
1631 if (!isnan(vp->pts))
1632 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1633 SDL_UnlockMutex(is->pictq.mutex);
1635 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1636 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1637 duration = vp_duration(is, vp, nextvp);
1638 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1639 is->frame_drops_late++;
1640 frame_queue_next(&is->pictq);
1645 if (is->subtitle_st) {
1646 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1647 sp = frame_queue_peek(&is->subpq);
1649 if (frame_queue_nb_remaining(&is->subpq) > 1)
1650 sp2 = frame_queue_peek_next(&is->subpq);
1654 if (sp->serial != is->subtitleq.serial
1655 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1656 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1660 for (i = 0; i < sp->sub.num_rects; i++) {
1661 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1665 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1666 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1667 memset(pixels, 0, sub_rect->w << 2);
1668 SDL_UnlockTexture(is->sub_texture);
1672 frame_queue_next(&is->subpq);
1679 frame_queue_next(&is->pictq);
1680 is->force_refresh = 1;
1682 if (is->step && !is->paused)
1683 stream_toggle_pause(is);
1686 /* display picture */
1687 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1690 is->force_refresh = 0;
1692 static int64_t last_time;
1694 int aqsize, vqsize, sqsize;
1697 cur_time = av_gettime_relative();
1698 if (!last_time || (cur_time - last_time) >= 30000) {
1703 aqsize = is->audioq.size;
1705 vqsize = is->videoq.size;
1706 if (is->subtitle_st)
1707 sqsize = is->subtitleq.size;
1709 if (is->audio_st && is->video_st)
1710 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1711 else if (is->video_st)
1712 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1713 else if (is->audio_st)
1714 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1715 av_log(NULL, AV_LOG_INFO,
1716 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1717 get_master_clock(is),
1718 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1720 is->frame_drops_early + is->frame_drops_late,
1724 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1725 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1727 last_time = cur_time;
1732 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1736 #if defined(DEBUG_SYNC)
1737 printf("frame_type=%c pts=%0.3f\n",
1738 av_get_picture_type_char(src_frame->pict_type), pts);
1741 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1744 vp->sar = src_frame->sample_aspect_ratio;
1747 vp->width = src_frame->width;
1748 vp->height = src_frame->height;
1749 vp->format = src_frame->format;
1752 vp->duration = duration;
1754 vp->serial = serial;
1756 set_default_window_size(vp->width, vp->height, vp->sar);
1758 av_frame_move_ref(vp->frame, src_frame);
1759 frame_queue_push(&is->pictq);
1763 static int get_video_frame(VideoState *is, AVFrame *frame)
1767 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1773 if (frame->pts != AV_NOPTS_VALUE)
1774 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1776 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1778 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1779 if (frame->pts != AV_NOPTS_VALUE) {
1780 double diff = dpts - get_master_clock(is);
1781 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1782 diff - is->frame_last_filter_delay < 0 &&
1783 is->viddec.pkt_serial == is->vidclk.serial &&
1784 is->videoq.nb_packets) {
1785 is->frame_drops_early++;
1786 av_frame_unref(frame);
1797 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1798 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1801 int nb_filters = graph->nb_filters;
1802 AVFilterInOut *outputs = NULL, *inputs = NULL;
1805 outputs = avfilter_inout_alloc();
1806 inputs = avfilter_inout_alloc();
1807 if (!outputs || !inputs) {
1808 ret = AVERROR(ENOMEM);
1812 outputs->name = av_strdup("in");
1813 outputs->filter_ctx = source_ctx;
1814 outputs->pad_idx = 0;
1815 outputs->next = NULL;
1817 inputs->name = av_strdup("out");
1818 inputs->filter_ctx = sink_ctx;
1819 inputs->pad_idx = 0;
1820 inputs->next = NULL;
1822 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1825 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1829 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1830 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1831 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1833 ret = avfilter_graph_config(graph, NULL);
1835 avfilter_inout_free(&outputs);
1836 avfilter_inout_free(&inputs);
1840 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1842 enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
1843 char sws_flags_str[512] = "";
1844 char buffersrc_args[256];
1846 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1847 AVCodecParameters *codecpar = is->video_st->codecpar;
1848 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1849 AVDictionaryEntry *e = NULL;
1850 int nb_pix_fmts = 0;
1853 for (i = 0; i < renderer_info.num_texture_formats; i++) {
1854 for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; j++) {
1855 if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
1856 pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
1861 pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
1863 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1864 if (!strcmp(e->key, "sws_flags")) {
1865 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1867 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1869 if (strlen(sws_flags_str))
1870 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1872 graph->scale_sws_opts = av_strdup(sws_flags_str);
1874 snprintf(buffersrc_args, sizeof(buffersrc_args),
1875 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1876 frame->width, frame->height, frame->format,
1877 is->video_st->time_base.num, is->video_st->time_base.den,
1878 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1879 if (fr.num && fr.den)
1880 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1882 if ((ret = avfilter_graph_create_filter(&filt_src,
1883 avfilter_get_by_name("buffer"),
1884 "ffplay_buffer", buffersrc_args, NULL,
1888 ret = avfilter_graph_create_filter(&filt_out,
1889 avfilter_get_by_name("buffersink"),
1890 "ffplay_buffersink", NULL, NULL, graph);
1894 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1897 last_filter = filt_out;
1899 /* Note: this macro adds a filter before the lastly added filter, so the
1900 * processing order of the filters is in reverse */
1901 #define INSERT_FILT(name, arg) do { \
1902 AVFilterContext *filt_ctx; \
1904 ret = avfilter_graph_create_filter(&filt_ctx, \
1905 avfilter_get_by_name(name), \
1906 "ffplay_" name, arg, NULL, graph); \
1910 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1914 last_filter = filt_ctx; \
1918 double theta = get_rotation(is->video_st);
1920 if (fabs(theta - 90) < 1.0) {
1921 INSERT_FILT("transpose", "clock");
1922 } else if (fabs(theta - 180) < 1.0) {
1923 INSERT_FILT("hflip", NULL);
1924 INSERT_FILT("vflip", NULL);
1925 } else if (fabs(theta - 270) < 1.0) {
1926 INSERT_FILT("transpose", "cclock");
1927 } else if (fabs(theta) > 1.0) {
1928 char rotate_buf[64];
1929 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1930 INSERT_FILT("rotate", rotate_buf);
1934 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1937 is->in_video_filter = filt_src;
1938 is->out_video_filter = filt_out;
1944 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1946 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1947 int sample_rates[2] = { 0, -1 };
1948 int64_t channel_layouts[2] = { 0, -1 };
1949 int channels[2] = { 0, -1 };
1950 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1951 char aresample_swr_opts[512] = "";
1952 AVDictionaryEntry *e = NULL;
1953 char asrc_args[256];
1956 avfilter_graph_free(&is->agraph);
1957 if (!(is->agraph = avfilter_graph_alloc()))
1958 return AVERROR(ENOMEM);
1959 is->agraph->nb_threads = filter_nbthreads;
1961 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1962 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1963 if (strlen(aresample_swr_opts))
1964 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1965 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1967 ret = snprintf(asrc_args, sizeof(asrc_args),
1968 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1969 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1970 is->audio_filter_src.channels,
1971 1, is->audio_filter_src.freq);
1972 if (is->audio_filter_src.channel_layout)
1973 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1974 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1976 ret = avfilter_graph_create_filter(&filt_asrc,
1977 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1978 asrc_args, NULL, is->agraph);
1983 ret = avfilter_graph_create_filter(&filt_asink,
1984 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1985 NULL, NULL, is->agraph);
1989 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1991 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1994 if (force_output_format) {
1995 channel_layouts[0] = is->audio_tgt.channel_layout;
1996 channels [0] = is->audio_tgt.channels;
1997 sample_rates [0] = is->audio_tgt.freq;
1998 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2000 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2002 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2004 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2009 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2012 is->in_audio_filter = filt_asrc;
2013 is->out_audio_filter = filt_asink;
2017 avfilter_graph_free(&is->agraph);
2020 #endif /* CONFIG_AVFILTER */
2022 static int audio_thread(void *arg)
2024 VideoState *is = arg;
2025 AVFrame *frame = av_frame_alloc();
2028 int last_serial = -1;
2029 int64_t dec_channel_layout;
2037 return AVERROR(ENOMEM);
2040 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2044 tb = (AVRational){1, frame->sample_rate};
2047 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
2050 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2051 frame->format, frame->channels) ||
2052 is->audio_filter_src.channel_layout != dec_channel_layout ||
2053 is->audio_filter_src.freq != frame->sample_rate ||
2054 is->auddec.pkt_serial != last_serial;
2057 char buf1[1024], buf2[1024];
2058 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2059 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2060 av_log(NULL, AV_LOG_DEBUG,
2061 "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",
2062 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2063 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2065 is->audio_filter_src.fmt = frame->format;
2066 is->audio_filter_src.channels = frame->channels;
2067 is->audio_filter_src.channel_layout = dec_channel_layout;
2068 is->audio_filter_src.freq = frame->sample_rate;
2069 last_serial = is->auddec.pkt_serial;
2071 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2075 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2078 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2079 tb = av_buffersink_get_time_base(is->out_audio_filter);
2081 if (!(af = frame_queue_peek_writable(&is->sampq)))
2084 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2085 af->pos = frame->pkt_pos;
2086 af->serial = is->auddec.pkt_serial;
2087 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2089 av_frame_move_ref(af->frame, frame);
2090 frame_queue_push(&is->sampq);
2093 if (is->audioq.serial != is->auddec.pkt_serial)
2096 if (ret == AVERROR_EOF)
2097 is->auddec.finished = is->auddec.pkt_serial;
2100 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2103 avfilter_graph_free(&is->agraph);
2105 av_frame_free(&frame);
2109 static int decoder_start(Decoder *d, int (*fn)(void *), const char *thread_name, void* arg)
2111 packet_queue_start(d->queue);
2112 d->decoder_tid = SDL_CreateThread(fn, thread_name, arg);
2113 if (!d->decoder_tid) {
2114 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2115 return AVERROR(ENOMEM);
2120 static int video_thread(void *arg)
2122 VideoState *is = arg;
2123 AVFrame *frame = av_frame_alloc();
2127 AVRational tb = is->video_st->time_base;
2128 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2131 AVFilterGraph *graph = NULL;
2132 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2135 enum AVPixelFormat last_format = -2;
2136 int last_serial = -1;
2137 int last_vfilter_idx = 0;
2141 return AVERROR(ENOMEM);
2144 ret = get_video_frame(is, frame);
2151 if ( last_w != frame->width
2152 || last_h != frame->height
2153 || last_format != frame->format
2154 || last_serial != is->viddec.pkt_serial
2155 || last_vfilter_idx != is->vfilter_idx) {
2156 av_log(NULL, AV_LOG_DEBUG,
2157 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2159 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2160 frame->width, frame->height,
2161 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2162 avfilter_graph_free(&graph);
2163 graph = avfilter_graph_alloc();
2165 ret = AVERROR(ENOMEM);
2168 graph->nb_threads = filter_nbthreads;
2169 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2171 event.type = FF_QUIT_EVENT;
2172 event.user.data1 = is;
2173 SDL_PushEvent(&event);
2176 filt_in = is->in_video_filter;
2177 filt_out = is->out_video_filter;
2178 last_w = frame->width;
2179 last_h = frame->height;
2180 last_format = frame->format;
2181 last_serial = is->viddec.pkt_serial;
2182 last_vfilter_idx = is->vfilter_idx;
2183 frame_rate = av_buffersink_get_frame_rate(filt_out);
2186 ret = av_buffersrc_add_frame(filt_in, frame);
2191 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2193 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2195 if (ret == AVERROR_EOF)
2196 is->viddec.finished = is->viddec.pkt_serial;
2201 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2202 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2203 is->frame_last_filter_delay = 0;
2204 tb = av_buffersink_get_time_base(filt_out);
2206 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2207 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2208 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2209 av_frame_unref(frame);
2211 if (is->videoq.serial != is->viddec.pkt_serial)
2221 avfilter_graph_free(&graph);
2223 av_frame_free(&frame);
2227 static int subtitle_thread(void *arg)
2229 VideoState *is = arg;
2235 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2238 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2243 if (got_subtitle && sp->sub.format == 0) {
2244 if (sp->sub.pts != AV_NOPTS_VALUE)
2245 pts = sp->sub.pts / (double)AV_TIME_BASE;
2247 sp->serial = is->subdec.pkt_serial;
2248 sp->width = is->subdec.avctx->width;
2249 sp->height = is->subdec.avctx->height;
2252 /* now we can update the picture count */
2253 frame_queue_push(&is->subpq);
2254 } else if (got_subtitle) {
2255 avsubtitle_free(&sp->sub);
2261 /* copy samples for viewing in editor window */
2262 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2266 size = samples_size / sizeof(short);
2268 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2271 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2273 is->sample_array_index += len;
2274 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2275 is->sample_array_index = 0;
2280 /* return the wanted number of samples to get better sync if sync_type is video
2281 * or external master clock */
2282 static int synchronize_audio(VideoState *is, int nb_samples)
2284 int wanted_nb_samples = nb_samples;
2286 /* if not master, then we try to remove or add samples to correct the clock */
2287 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2288 double diff, avg_diff;
2289 int min_nb_samples, max_nb_samples;
2291 diff = get_clock(&is->audclk) - get_master_clock(is);
2293 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2294 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2295 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2296 /* not enough measures to have a correct estimate */
2297 is->audio_diff_avg_count++;
2299 /* estimate the A-V difference */
2300 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2302 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2303 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2304 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2305 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2306 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2308 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2309 diff, avg_diff, wanted_nb_samples - nb_samples,
2310 is->audio_clock, is->audio_diff_threshold);
2313 /* too big difference : may be initial PTS errors, so
2315 is->audio_diff_avg_count = 0;
2316 is->audio_diff_cum = 0;
2320 return wanted_nb_samples;
2324 * Decode one audio frame and return its uncompressed size.
2326 * The processed audio frame is decoded, converted if required, and
2327 * stored in is->audio_buf, with size in bytes given by the return
2330 static int audio_decode_frame(VideoState *is)
2332 int data_size, resampled_data_size;
2333 int64_t dec_channel_layout;
2334 av_unused double audio_clock0;
2335 int wanted_nb_samples;
2343 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2344 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2349 if (!(af = frame_queue_peek_readable(&is->sampq)))
2351 frame_queue_next(&is->sampq);
2352 } while (af->serial != is->audioq.serial);
2354 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2355 af->frame->nb_samples,
2356 af->frame->format, 1);
2358 dec_channel_layout =
2359 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2360 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2361 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2363 if (af->frame->format != is->audio_src.fmt ||
2364 dec_channel_layout != is->audio_src.channel_layout ||
2365 af->frame->sample_rate != is->audio_src.freq ||
2366 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2367 swr_free(&is->swr_ctx);
2368 is->swr_ctx = swr_alloc_set_opts(NULL,
2369 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2370 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2372 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2373 av_log(NULL, AV_LOG_ERROR,
2374 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2375 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2376 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2377 swr_free(&is->swr_ctx);
2380 is->audio_src.channel_layout = dec_channel_layout;
2381 is->audio_src.channels = af->frame->channels;
2382 is->audio_src.freq = af->frame->sample_rate;
2383 is->audio_src.fmt = af->frame->format;
2387 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2388 uint8_t **out = &is->audio_buf1;
2389 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2390 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2393 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2396 if (wanted_nb_samples != af->frame->nb_samples) {
2397 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2398 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2399 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2403 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2404 if (!is->audio_buf1)
2405 return AVERROR(ENOMEM);
2406 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2408 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2411 if (len2 == out_count) {
2412 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2413 if (swr_init(is->swr_ctx) < 0)
2414 swr_free(&is->swr_ctx);
2416 is->audio_buf = is->audio_buf1;
2417 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2419 is->audio_buf = af->frame->data[0];
2420 resampled_data_size = data_size;
2423 audio_clock0 = is->audio_clock;
2424 /* update the audio clock with the pts */
2425 if (!isnan(af->pts))
2426 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2428 is->audio_clock = NAN;
2429 is->audio_clock_serial = af->serial;
2432 static double last_clock;
2433 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2434 is->audio_clock - last_clock,
2435 is->audio_clock, audio_clock0);
2436 last_clock = is->audio_clock;
2439 return resampled_data_size;
2442 /* prepare a new audio buffer */
2443 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2445 VideoState *is = opaque;
2446 int audio_size, len1;
2448 audio_callback_time = av_gettime_relative();
2451 if (is->audio_buf_index >= is->audio_buf_size) {
2452 audio_size = audio_decode_frame(is);
2453 if (audio_size < 0) {
2454 /* if error, just output silence */
2455 is->audio_buf = NULL;
2456 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2458 if (is->show_mode != SHOW_MODE_VIDEO)
2459 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2460 is->audio_buf_size = audio_size;
2462 is->audio_buf_index = 0;
2464 len1 = is->audio_buf_size - is->audio_buf_index;
2467 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2468 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2470 memset(stream, 0, len1);
2471 if (!is->muted && is->audio_buf)
2472 SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
2476 is->audio_buf_index += len1;
2478 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2479 /* Let's assume the audio driver that is used by SDL has two periods. */
2480 if (!isnan(is->audio_clock)) {
2481 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);
2482 sync_clock_to_slave(&is->extclk, &is->audclk);
2486 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2488 SDL_AudioSpec wanted_spec, spec;
2490 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2491 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2492 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2494 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2496 wanted_nb_channels = atoi(env);
2497 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2499 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2500 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2501 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2503 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2504 wanted_spec.channels = wanted_nb_channels;
2505 wanted_spec.freq = wanted_sample_rate;
2506 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2507 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2510 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2511 next_sample_rate_idx--;
2512 wanted_spec.format = AUDIO_S16SYS;
2513 wanted_spec.silence = 0;
2514 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2515 wanted_spec.callback = sdl_audio_callback;
2516 wanted_spec.userdata = opaque;
2517 while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
2518 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2519 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2520 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2521 if (!wanted_spec.channels) {
2522 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2523 wanted_spec.channels = wanted_nb_channels;
2524 if (!wanted_spec.freq) {
2525 av_log(NULL, AV_LOG_ERROR,
2526 "No more combinations to try, audio open failed\n");
2530 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2532 if (spec.format != AUDIO_S16SYS) {
2533 av_log(NULL, AV_LOG_ERROR,
2534 "SDL advised audio format %d is not supported!\n", spec.format);
2537 if (spec.channels != wanted_spec.channels) {
2538 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2539 if (!wanted_channel_layout) {
2540 av_log(NULL, AV_LOG_ERROR,
2541 "SDL advised channel count %d is not supported!\n", spec.channels);
2546 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2547 audio_hw_params->freq = spec.freq;
2548 audio_hw_params->channel_layout = wanted_channel_layout;
2549 audio_hw_params->channels = spec.channels;
2550 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2551 audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
2552 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2553 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2559 /* open a given stream. Return 0 if OK */
2560 static int stream_component_open(VideoState *is, int stream_index)
2562 AVFormatContext *ic = is->ic;
2563 AVCodecContext *avctx;
2565 const char *forced_codec_name = NULL;
2566 AVDictionary *opts = NULL;
2567 AVDictionaryEntry *t = NULL;
2568 int sample_rate, nb_channels;
2569 int64_t channel_layout;
2571 int stream_lowres = lowres;
2573 if (stream_index < 0 || stream_index >= ic->nb_streams)
2576 avctx = avcodec_alloc_context3(NULL);
2578 return AVERROR(ENOMEM);
2580 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2583 avctx->pkt_timebase = ic->streams[stream_index]->time_base;
2585 codec = avcodec_find_decoder(avctx->codec_id);
2587 switch(avctx->codec_type){
2588 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2589 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2590 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2592 if (forced_codec_name)
2593 codec = avcodec_find_decoder_by_name(forced_codec_name);
2595 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2596 "No codec could be found with name '%s'\n", forced_codec_name);
2597 else av_log(NULL, AV_LOG_WARNING,
2598 "No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
2599 ret = AVERROR(EINVAL);
2603 avctx->codec_id = codec->id;
2604 if (stream_lowres > codec->max_lowres) {
2605 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2607 stream_lowres = codec->max_lowres;
2609 avctx->lowres = stream_lowres;
2612 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2614 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2615 if (!av_dict_get(opts, "threads", NULL, 0))
2616 av_dict_set(&opts, "threads", "auto", 0);
2618 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2619 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2620 av_dict_set(&opts, "refcounted_frames", "1", 0);
2621 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2624 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2625 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2626 ret = AVERROR_OPTION_NOT_FOUND;
2631 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2632 switch (avctx->codec_type) {
2633 case AVMEDIA_TYPE_AUDIO:
2636 AVFilterContext *sink;
2638 is->audio_filter_src.freq = avctx->sample_rate;
2639 is->audio_filter_src.channels = avctx->channels;
2640 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2641 is->audio_filter_src.fmt = avctx->sample_fmt;
2642 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2644 sink = is->out_audio_filter;
2645 sample_rate = av_buffersink_get_sample_rate(sink);
2646 nb_channels = av_buffersink_get_channels(sink);
2647 channel_layout = av_buffersink_get_channel_layout(sink);
2650 sample_rate = avctx->sample_rate;
2651 nb_channels = avctx->channels;
2652 channel_layout = avctx->channel_layout;
2655 /* prepare audio output */
2656 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2658 is->audio_hw_buf_size = ret;
2659 is->audio_src = is->audio_tgt;
2660 is->audio_buf_size = 0;
2661 is->audio_buf_index = 0;
2663 /* init averaging filter */
2664 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2665 is->audio_diff_avg_count = 0;
2666 /* since we do not have a precise anough audio FIFO fullness,
2667 we correct audio sync only if larger than this threshold */
2668 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2670 is->audio_stream = stream_index;
2671 is->audio_st = ic->streams[stream_index];
2673 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2674 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2675 is->auddec.start_pts = is->audio_st->start_time;
2676 is->auddec.start_pts_tb = is->audio_st->time_base;
2678 if ((ret = decoder_start(&is->auddec, audio_thread, "audio_decoder", is)) < 0)
2680 SDL_PauseAudioDevice(audio_dev, 0);
2682 case AVMEDIA_TYPE_VIDEO:
2683 is->video_stream = stream_index;
2684 is->video_st = ic->streams[stream_index];
2686 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2687 if ((ret = decoder_start(&is->viddec, video_thread, "video_decoder", is)) < 0)
2689 is->queue_attachments_req = 1;
2691 case AVMEDIA_TYPE_SUBTITLE:
2692 is->subtitle_stream = stream_index;
2693 is->subtitle_st = ic->streams[stream_index];
2695 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2696 if ((ret = decoder_start(&is->subdec, subtitle_thread, "subtitle_decoder", is)) < 0)
2705 avcodec_free_context(&avctx);
2707 av_dict_free(&opts);
2712 static int decode_interrupt_cb(void *ctx)
2714 VideoState *is = ctx;
2715 return is->abort_request;
2718 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2719 return stream_id < 0 ||
2720 queue->abort_request ||
2721 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2722 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2725 static int is_realtime(AVFormatContext *s)
2727 if( !strcmp(s->iformat->name, "rtp")
2728 || !strcmp(s->iformat->name, "rtsp")
2729 || !strcmp(s->iformat->name, "sdp")
2733 if(s->pb && ( !strncmp(s->url, "rtp:", 4)
2734 || !strncmp(s->url, "udp:", 4)
2741 /* this thread gets the stream from the disk or the network */
2742 static int read_thread(void *arg)
2744 VideoState *is = arg;
2745 AVFormatContext *ic = NULL;
2747 int st_index[AVMEDIA_TYPE_NB];
2748 AVPacket pkt1, *pkt = &pkt1;
2749 int64_t stream_start_time;
2750 int pkt_in_play_range = 0;
2751 AVDictionaryEntry *t;
2752 SDL_mutex *wait_mutex = SDL_CreateMutex();
2753 int scan_all_pmts_set = 0;
2757 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2758 ret = AVERROR(ENOMEM);
2762 memset(st_index, -1, sizeof(st_index));
2763 is->last_video_stream = is->video_stream = -1;
2764 is->last_audio_stream = is->audio_stream = -1;
2765 is->last_subtitle_stream = is->subtitle_stream = -1;
2768 ic = avformat_alloc_context();
2770 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2771 ret = AVERROR(ENOMEM);
2774 ic->interrupt_callback.callback = decode_interrupt_cb;
2775 ic->interrupt_callback.opaque = is;
2776 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2777 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2778 scan_all_pmts_set = 1;
2780 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2782 print_error(is->filename, err);
2786 if (scan_all_pmts_set)
2787 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2789 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2790 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2791 ret = AVERROR_OPTION_NOT_FOUND;
2797 ic->flags |= AVFMT_FLAG_GENPTS;
2799 av_format_inject_global_side_data(ic);
2801 if (find_stream_info) {
2802 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2803 int orig_nb_streams = ic->nb_streams;
2805 err = avformat_find_stream_info(ic, opts);
2807 for (i = 0; i < orig_nb_streams; i++)
2808 av_dict_free(&opts[i]);
2812 av_log(NULL, AV_LOG_WARNING,
2813 "%s: could not find codec parameters\n", is->filename);
2820 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2822 if (seek_by_bytes < 0)
2823 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2825 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2827 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2828 window_title = av_asprintf("%s - %s", t->value, input_filename);
2830 /* if seeking requested, we execute it */
2831 if (start_time != AV_NOPTS_VALUE) {
2834 timestamp = start_time;
2835 /* add the stream start time */
2836 if (ic->start_time != AV_NOPTS_VALUE)
2837 timestamp += ic->start_time;
2838 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2840 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2841 is->filename, (double)timestamp / AV_TIME_BASE);
2845 is->realtime = is_realtime(ic);
2848 av_dump_format(ic, 0, is->filename, 0);
2850 for (i = 0; i < ic->nb_streams; i++) {
2851 AVStream *st = ic->streams[i];
2852 enum AVMediaType type = st->codecpar->codec_type;
2853 st->discard = AVDISCARD_ALL;
2854 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2855 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2858 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2859 if (wanted_stream_spec[i] && st_index[i] == -1) {
2860 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));
2861 st_index[i] = INT_MAX;
2866 st_index[AVMEDIA_TYPE_VIDEO] =
2867 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2868 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2870 st_index[AVMEDIA_TYPE_AUDIO] =
2871 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2872 st_index[AVMEDIA_TYPE_AUDIO],
2873 st_index[AVMEDIA_TYPE_VIDEO],
2875 if (!video_disable && !subtitle_disable)
2876 st_index[AVMEDIA_TYPE_SUBTITLE] =
2877 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2878 st_index[AVMEDIA_TYPE_SUBTITLE],
2879 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2880 st_index[AVMEDIA_TYPE_AUDIO] :
2881 st_index[AVMEDIA_TYPE_VIDEO]),
2884 is->show_mode = show_mode;
2885 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2886 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2887 AVCodecParameters *codecpar = st->codecpar;
2888 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2889 if (codecpar->width)
2890 set_default_window_size(codecpar->width, codecpar->height, sar);
2893 /* open the streams */
2894 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2895 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2899 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2900 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2902 if (is->show_mode == SHOW_MODE_NONE)
2903 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2905 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2906 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2909 if (is->video_stream < 0 && is->audio_stream < 0) {
2910 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2916 if (infinite_buffer < 0 && is->realtime)
2917 infinite_buffer = 1;
2920 if (is->abort_request)
2922 if (is->paused != is->last_paused) {
2923 is->last_paused = is->paused;
2925 is->read_pause_return = av_read_pause(ic);
2929 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2931 (!strcmp(ic->iformat->name, "rtsp") ||
2932 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2933 /* wait 10 ms to avoid trying to get another packet */
2940 int64_t seek_target = is->seek_pos;
2941 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2942 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2943 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2944 // of the seek_pos/seek_rel variables
2946 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2948 av_log(NULL, AV_LOG_ERROR,
2949 "%s: error while seeking\n", is->ic->url);
2951 if (is->audio_stream >= 0) {
2952 packet_queue_flush(&is->audioq);
2953 packet_queue_put(&is->audioq, &flush_pkt);
2955 if (is->subtitle_stream >= 0) {
2956 packet_queue_flush(&is->subtitleq);
2957 packet_queue_put(&is->subtitleq, &flush_pkt);
2959 if (is->video_stream >= 0) {
2960 packet_queue_flush(&is->videoq);
2961 packet_queue_put(&is->videoq, &flush_pkt);
2963 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2964 set_clock(&is->extclk, NAN, 0);
2966 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2970 is->queue_attachments_req = 1;
2973 step_to_next_frame(is);
2975 if (is->queue_attachments_req) {
2976 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2977 AVPacket copy = { 0 };
2978 if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0)
2980 packet_queue_put(&is->videoq, ©);
2981 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2983 is->queue_attachments_req = 0;
2986 /* if the queue are full, no need to read more */
2987 if (infinite_buffer<1 &&
2988 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2989 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2990 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2991 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2993 SDL_LockMutex(wait_mutex);
2994 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2995 SDL_UnlockMutex(wait_mutex);
2999 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3000 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3001 if (loop != 1 && (!loop || --loop)) {
3002 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3003 } else if (autoexit) {
3008 ret = av_read_frame(ic, pkt);
3010 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3011 if (is->video_stream >= 0)
3012 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3013 if (is->audio_stream >= 0)
3014 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3015 if (is->subtitle_stream >= 0)
3016 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3019 if (ic->pb && ic->pb->error)
3021 SDL_LockMutex(wait_mutex);
3022 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3023 SDL_UnlockMutex(wait_mutex);
3028 /* check if packet is in play range specified by user, then queue, otherwise discard */
3029 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3030 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3031 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3032 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3033 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3034 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3035 <= ((double)duration / 1000000);
3036 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3037 packet_queue_put(&is->audioq, pkt);
3038 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3039 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3040 packet_queue_put(&is->videoq, pkt);
3041 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3042 packet_queue_put(&is->subtitleq, pkt);
3044 av_packet_unref(pkt);
3051 avformat_close_input(&ic);
3056 event.type = FF_QUIT_EVENT;
3057 event.user.data1 = is;
3058 SDL_PushEvent(&event);
3060 SDL_DestroyMutex(wait_mutex);
3064 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3068 is = av_mallocz(sizeof(VideoState));
3071 is->filename = av_strdup(filename);
3074 is->iformat = iformat;
3078 /* start video display */
3079 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3081 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3083 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3086 if (packet_queue_init(&is->videoq) < 0 ||
3087 packet_queue_init(&is->audioq) < 0 ||
3088 packet_queue_init(&is->subtitleq) < 0)
3091 if (!(is->continue_read_thread = SDL_CreateCond())) {
3092 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3096 init_clock(&is->vidclk, &is->videoq.serial);
3097 init_clock(&is->audclk, &is->audioq.serial);
3098 init_clock(&is->extclk, &is->extclk.serial);
3099 is->audio_clock_serial = -1;
3100 if (startup_volume < 0)
3101 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3102 if (startup_volume > 100)
3103 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3104 startup_volume = av_clip(startup_volume, 0, 100);
3105 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3106 is->audio_volume = startup_volume;
3108 is->av_sync_type = av_sync_type;
3109 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3110 if (!is->read_tid) {
3111 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3119 static void stream_cycle_channel(VideoState *is, int codec_type)
3121 AVFormatContext *ic = is->ic;
3122 int start_index, stream_index;
3125 AVProgram *p = NULL;
3126 int nb_streams = is->ic->nb_streams;
3128 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3129 start_index = is->last_video_stream;
3130 old_index = is->video_stream;
3131 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3132 start_index = is->last_audio_stream;
3133 old_index = is->audio_stream;
3135 start_index = is->last_subtitle_stream;
3136 old_index = is->subtitle_stream;
3138 stream_index = start_index;
3140 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3141 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3143 nb_streams = p->nb_stream_indexes;
3144 for (start_index = 0; start_index < nb_streams; start_index++)
3145 if (p->stream_index[start_index] == stream_index)
3147 if (start_index == nb_streams)
3149 stream_index = start_index;
3154 if (++stream_index >= nb_streams)
3156 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3159 is->last_subtitle_stream = -1;
3162 if (start_index == -1)
3166 if (stream_index == start_index)
3168 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3169 if (st->codecpar->codec_type == codec_type) {
3170 /* check that parameters are OK */
3171 switch (codec_type) {
3172 case AVMEDIA_TYPE_AUDIO:
3173 if (st->codecpar->sample_rate != 0 &&
3174 st->codecpar->channels != 0)
3177 case AVMEDIA_TYPE_VIDEO:
3178 case AVMEDIA_TYPE_SUBTITLE:
3186 if (p && stream_index != -1)
3187 stream_index = p->stream_index[stream_index];
3188 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3189 av_get_media_type_string(codec_type),
3193 stream_component_close(is, old_index);
3194 stream_component_open(is, stream_index);
3198 static void toggle_full_screen(VideoState *is)
3200 is_full_screen = !is_full_screen;
3201 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3204 static void toggle_audio_display(VideoState *is)
3206 int next = is->show_mode;
3208 next = (next + 1) % SHOW_MODE_NB;
3209 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3210 if (is->show_mode != next) {
3211 is->force_refresh = 1;
3212 is->show_mode = next;
3216 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3217 double remaining_time = 0.0;
3219 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3220 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3224 if (remaining_time > 0.0)
3225 av_usleep((int64_t)(remaining_time * 1000000.0));
3226 remaining_time = REFRESH_RATE;
3227 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3228 video_refresh(is, &remaining_time);
3233 static void seek_chapter(VideoState *is, int incr)
3235 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3238 if (!is->ic->nb_chapters)
3241 /* find the current chapter */
3242 for (i = 0; i < is->ic->nb_chapters; i++) {
3243 AVChapter *ch = is->ic->chapters[i];
3244 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3252 if (i >= is->ic->nb_chapters)
3255 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3256 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3257 AV_TIME_BASE_Q), 0, 0);
3260 /* handle an event sent by the GUI */
3261 static void event_loop(VideoState *cur_stream)
3264 double incr, pos, frac;
3268 refresh_loop_wait_event(cur_stream, &event);
3269 switch (event.type) {
3271 if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
3272 do_exit(cur_stream);
3275 // If we don't yet have a window, skip all key events, because read_thread might still be initializing...
3276 if (!cur_stream->width)
3278 switch (event.key.keysym.sym) {
3280 toggle_full_screen(cur_stream);
3281 cur_stream->force_refresh = 1;
3285 toggle_pause(cur_stream);
3288 toggle_mute(cur_stream);
3290 case SDLK_KP_MULTIPLY:
3292 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3294 case SDLK_KP_DIVIDE:
3296 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3298 case SDLK_s: // S: Step to next frame
3299 step_to_next_frame(cur_stream);
3302 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3305 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3308 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3309 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3310 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3313 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3317 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3318 if (++cur_stream->vfilter_idx >= nb_vfilters)
3319 cur_stream->vfilter_idx = 0;
3321 cur_stream->vfilter_idx = 0;
3322 toggle_audio_display(cur_stream);
3325 toggle_audio_display(cur_stream);
3329 if (cur_stream->ic->nb_chapters <= 1) {
3333 seek_chapter(cur_stream, 1);
3336 if (cur_stream->ic->nb_chapters <= 1) {
3340 seek_chapter(cur_stream, -1);
3343 incr = seek_interval ? -seek_interval : -10.0;
3346 incr = seek_interval ? seek_interval : 10.0;
3354 if (seek_by_bytes) {
3356 if (pos < 0 && cur_stream->video_stream >= 0)
3357 pos = frame_queue_last_pos(&cur_stream->pictq);
3358 if (pos < 0 && cur_stream->audio_stream >= 0)
3359 pos = frame_queue_last_pos(&cur_stream->sampq);
3361 pos = avio_tell(cur_stream->ic->pb);
3362 if (cur_stream->ic->bit_rate)
3363 incr *= cur_stream->ic->bit_rate / 8.0;
3367 stream_seek(cur_stream, pos, incr, 1);
3369 pos = get_master_clock(cur_stream);
3371 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3373 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3374 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3375 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3382 case SDL_MOUSEBUTTONDOWN:
3383 if (exit_on_mousedown) {
3384 do_exit(cur_stream);
3387 if (event.button.button == SDL_BUTTON_LEFT) {
3388 static int64_t last_mouse_left_click = 0;
3389 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3390 toggle_full_screen(cur_stream);
3391 cur_stream->force_refresh = 1;
3392 last_mouse_left_click = 0;
3394 last_mouse_left_click = av_gettime_relative();
3397 case SDL_MOUSEMOTION:
3398 if (cursor_hidden) {
3402 cursor_last_shown = av_gettime_relative();
3403 if (event.type == SDL_MOUSEBUTTONDOWN) {
3404 if (event.button.button != SDL_BUTTON_RIGHT)
3408 if (!(event.motion.state & SDL_BUTTON_RMASK))
3412 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3413 uint64_t size = avio_size(cur_stream->ic->pb);
3414 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3418 int tns, thh, tmm, tss;
3419 tns = cur_stream->ic->duration / 1000000LL;
3421 tmm = (tns % 3600) / 60;
3423 frac = x / cur_stream->width;
3426 mm = (ns % 3600) / 60;
3428 av_log(NULL, AV_LOG_INFO,
3429 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3430 hh, mm, ss, thh, tmm, tss);
3431 ts = frac * cur_stream->ic->duration;
3432 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3433 ts += cur_stream->ic->start_time;
3434 stream_seek(cur_stream, ts, 0, 0);
3437 case SDL_WINDOWEVENT:
3438 switch (event.window.event) {
3439 case SDL_WINDOWEVENT_SIZE_CHANGED:
3440 screen_width = cur_stream->width = event.window.data1;
3441 screen_height = cur_stream->height = event.window.data2;
3442 if (cur_stream->vis_texture) {
3443 SDL_DestroyTexture(cur_stream->vis_texture);
3444 cur_stream->vis_texture = NULL;
3446 case SDL_WINDOWEVENT_EXPOSED:
3447 cur_stream->force_refresh = 1;
3452 do_exit(cur_stream);
3460 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3462 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3463 return opt_default(NULL, "video_size", arg);
3466 static int opt_width(void *optctx, const char *opt, const char *arg)
3468 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3472 static int opt_height(void *optctx, const char *opt, const char *arg)
3474 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3478 static int opt_format(void *optctx, const char *opt, const char *arg)
3480 file_iformat = av_find_input_format(arg);
3481 if (!file_iformat) {
3482 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3483 return AVERROR(EINVAL);
3488 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3490 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3491 return opt_default(NULL, "pixel_format", arg);
3494 static int opt_sync(void *optctx, const char *opt, const char *arg)
3496 if (!strcmp(arg, "audio"))
3497 av_sync_type = AV_SYNC_AUDIO_MASTER;
3498 else if (!strcmp(arg, "video"))
3499 av_sync_type = AV_SYNC_VIDEO_MASTER;
3500 else if (!strcmp(arg, "ext"))
3501 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3503 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3509 static int opt_seek(void *optctx, const char *opt, const char *arg)
3511 start_time = parse_time_or_die(opt, arg, 1);
3515 static int opt_duration(void *optctx, const char *opt, const char *arg)
3517 duration = parse_time_or_die(opt, arg, 1);
3521 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3523 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3524 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3525 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3526 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3530 static void opt_input_file(void *optctx, const char *filename)
3532 if (input_filename) {
3533 av_log(NULL, AV_LOG_FATAL,
3534 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3535 filename, input_filename);
3538 if (!strcmp(filename, "-"))
3540 input_filename = filename;
3543 static int opt_codec(void *optctx, const char *opt, const char *arg)
3545 const char *spec = strchr(opt, ':');
3547 av_log(NULL, AV_LOG_ERROR,
3548 "No media specifier was specified in '%s' in option '%s'\n",
3550 return AVERROR(EINVAL);
3554 case 'a' : audio_codec_name = arg; break;
3555 case 's' : subtitle_codec_name = arg; break;
3556 case 'v' : video_codec_name = arg; break;
3558 av_log(NULL, AV_LOG_ERROR,
3559 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3560 return AVERROR(EINVAL);
3567 static const OptionDef options[] = {
3568 CMDUTILS_COMMON_OPTIONS
3569 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3570 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3571 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3572 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3573 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3574 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3575 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3576 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3577 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3578 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3579 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3580 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3581 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3582 { "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
3583 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3584 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3585 { "alwaysontop", OPT_BOOL, { &alwaysontop }, "window always on top" },
3586 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3587 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3588 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3589 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3590 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3591 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3592 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3593 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3594 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3595 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3596 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3597 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3598 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3599 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3600 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3601 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3602 { "left", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_left }, "set the x position for the left of the window", "x pos" },
3603 { "top", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_top }, "set the y position for the top of the window", "y pos" },
3605 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3606 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3608 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3609 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3610 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3611 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3612 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3613 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3614 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3615 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3616 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3617 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3618 "read and decode the streams to fill missing information with heuristics" },
3619 { "filter_threads", HAS_ARG | OPT_INT | OPT_EXPERT, { &filter_nbthreads }, "number of filter threads per graph" },
3623 static void show_usage(void)
3625 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3626 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3627 av_log(NULL, AV_LOG_INFO, "\n");
3630 void show_help_default(const char *opt, const char *arg)
3632 av_log_set_callback(log_callback_help);
3634 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3635 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3637 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3638 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3639 #if !CONFIG_AVFILTER
3640 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3642 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3644 printf("\nWhile playing:\n"
3646 "f toggle full screen\n"
3649 "9, 0 decrease and increase volume respectively\n"
3650 "/, * decrease and increase volume respectively\n"
3651 "a cycle audio channel in the current program\n"
3652 "v cycle video channel\n"
3653 "t cycle subtitle channel in the current program\n"
3655 "w cycle video filters or show modes\n"
3656 "s activate frame-step mode\n"
3657 "left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
3658 "down/up seek backward/forward 1 minute\n"
3659 "page down/page up seek backward/forward 10 minutes\n"
3660 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3661 "left double-click toggle full screen\n"
3665 /* Called from the main */
3666 int main(int argc, char **argv)
3673 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3674 parse_loglevel(argc, argv, options);
3676 /* register all codecs, demux and protocols */
3678 avdevice_register_all();
3680 avformat_network_init();
3684 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3685 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3687 show_banner(argc, argv, options);
3689 parse_options(NULL, argc, argv, options, opt_input_file);
3691 if (!input_filename) {
3693 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3694 av_log(NULL, AV_LOG_FATAL,
3695 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3699 if (display_disable) {
3702 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3704 flags &= ~SDL_INIT_AUDIO;
3706 /* Try to work around an occasional ALSA buffer underflow issue when the
3707 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3708 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3709 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3711 if (display_disable)
3712 flags &= ~SDL_INIT_VIDEO;
3713 if (SDL_Init (flags)) {
3714 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3715 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3719 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3720 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3722 av_init_packet(&flush_pkt);
3723 flush_pkt.data = (uint8_t *)&flush_pkt;
3725 if (!display_disable) {
3726 int flags = SDL_WINDOW_HIDDEN;
3728 #if SDL_VERSION_ATLEAST(2,0,5)
3729 flags |= SDL_WINDOW_ALWAYS_ON_TOP;
3731 av_log(NULL, AV_LOG_WARNING, "Your SDL version doesn't support SDL_WINDOW_ALWAYS_ON_TOP. Feature will be inactive.\n");
3734 flags |= SDL_WINDOW_BORDERLESS;
3736 flags |= SDL_WINDOW_RESIZABLE;
3737 window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
3738 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
3740 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
3742 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
3743 renderer = SDL_CreateRenderer(window, -1, 0);
3746 if (!SDL_GetRendererInfo(renderer, &renderer_info))
3747 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
3750 if (!window || !renderer || !renderer_info.num_texture_formats) {
3751 av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
3756 is = stream_open(input_filename, file_iformat);
3758 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");