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 if (d->queue->serial == d->pkt_serial)
649 av_packet_unref(&pkt);
652 if (pkt.data == flush_pkt.data) {
653 avcodec_flush_buffers(d->avctx);
655 d->next_pts = d->start_pts;
656 d->next_pts_tb = d->start_pts_tb;
658 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
660 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
662 ret = AVERROR(EAGAIN);
664 if (got_frame && !pkt.data) {
665 d->packet_pending = 1;
666 av_packet_move_ref(&d->pkt, &pkt);
668 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
671 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
672 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
673 d->packet_pending = 1;
674 av_packet_move_ref(&d->pkt, &pkt);
677 av_packet_unref(&pkt);
682 static void decoder_destroy(Decoder *d) {
683 av_packet_unref(&d->pkt);
684 avcodec_free_context(&d->avctx);
687 static void frame_queue_unref_item(Frame *vp)
689 av_frame_unref(vp->frame);
690 avsubtitle_free(&vp->sub);
693 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
696 memset(f, 0, sizeof(FrameQueue));
697 if (!(f->mutex = SDL_CreateMutex())) {
698 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
699 return AVERROR(ENOMEM);
701 if (!(f->cond = SDL_CreateCond())) {
702 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
703 return AVERROR(ENOMEM);
706 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
707 f->keep_last = !!keep_last;
708 for (i = 0; i < f->max_size; i++)
709 if (!(f->queue[i].frame = av_frame_alloc()))
710 return AVERROR(ENOMEM);
714 static void frame_queue_destory(FrameQueue *f)
717 for (i = 0; i < f->max_size; i++) {
718 Frame *vp = &f->queue[i];
719 frame_queue_unref_item(vp);
720 av_frame_free(&vp->frame);
722 SDL_DestroyMutex(f->mutex);
723 SDL_DestroyCond(f->cond);
726 static void frame_queue_signal(FrameQueue *f)
728 SDL_LockMutex(f->mutex);
729 SDL_CondSignal(f->cond);
730 SDL_UnlockMutex(f->mutex);
733 static Frame *frame_queue_peek(FrameQueue *f)
735 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
738 static Frame *frame_queue_peek_next(FrameQueue *f)
740 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
743 static Frame *frame_queue_peek_last(FrameQueue *f)
745 return &f->queue[f->rindex];
748 static Frame *frame_queue_peek_writable(FrameQueue *f)
750 /* wait until we have space to put a new frame */
751 SDL_LockMutex(f->mutex);
752 while (f->size >= f->max_size &&
753 !f->pktq->abort_request) {
754 SDL_CondWait(f->cond, f->mutex);
756 SDL_UnlockMutex(f->mutex);
758 if (f->pktq->abort_request)
761 return &f->queue[f->windex];
764 static Frame *frame_queue_peek_readable(FrameQueue *f)
766 /* wait until we have a readable a new frame */
767 SDL_LockMutex(f->mutex);
768 while (f->size - f->rindex_shown <= 0 &&
769 !f->pktq->abort_request) {
770 SDL_CondWait(f->cond, f->mutex);
772 SDL_UnlockMutex(f->mutex);
774 if (f->pktq->abort_request)
777 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
780 static void frame_queue_push(FrameQueue *f)
782 if (++f->windex == f->max_size)
784 SDL_LockMutex(f->mutex);
786 SDL_CondSignal(f->cond);
787 SDL_UnlockMutex(f->mutex);
790 static void frame_queue_next(FrameQueue *f)
792 if (f->keep_last && !f->rindex_shown) {
796 frame_queue_unref_item(&f->queue[f->rindex]);
797 if (++f->rindex == f->max_size)
799 SDL_LockMutex(f->mutex);
801 SDL_CondSignal(f->cond);
802 SDL_UnlockMutex(f->mutex);
805 /* return the number of undisplayed frames in the queue */
806 static int frame_queue_nb_remaining(FrameQueue *f)
808 return f->size - f->rindex_shown;
811 /* return last shown position */
812 static int64_t frame_queue_last_pos(FrameQueue *f)
814 Frame *fp = &f->queue[f->rindex];
815 if (f->rindex_shown && fp->serial == f->pktq->serial)
821 static void decoder_abort(Decoder *d, FrameQueue *fq)
823 packet_queue_abort(d->queue);
824 frame_queue_signal(fq);
825 SDL_WaitThread(d->decoder_tid, NULL);
826 d->decoder_tid = NULL;
827 packet_queue_flush(d->queue);
830 static inline void fill_rectangle(int x, int y, int w, int h)
838 SDL_RenderFillRect(renderer, &rect);
841 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
845 if (!*texture || SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
849 SDL_DestroyTexture(*texture);
850 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
852 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
855 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
857 memset(pixels, 0, pitch * new_height);
858 SDL_UnlockTexture(*texture);
860 av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
865 static void calculate_display_rect(SDL_Rect *rect,
866 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
867 int pic_width, int pic_height, AVRational pic_sar)
869 AVRational aspect_ratio = pic_sar;
870 int64_t width, height, x, y;
872 if (av_cmp_q(aspect_ratio, av_make_q(0, 1)) <= 0)
873 aspect_ratio = av_make_q(1, 1);
875 aspect_ratio = av_mul_q(aspect_ratio, av_make_q(pic_width, pic_height));
877 /* XXX: we suppose the screen has a 1.0 pixel ratio */
879 width = av_rescale(height, aspect_ratio.num, aspect_ratio.den) & ~1;
880 if (width > scr_width) {
882 height = av_rescale(width, aspect_ratio.den, aspect_ratio.num) & ~1;
884 x = (scr_width - width) / 2;
885 y = (scr_height - height) / 2;
886 rect->x = scr_xleft + x;
887 rect->y = scr_ytop + y;
888 rect->w = FFMAX((int)width, 1);
889 rect->h = FFMAX((int)height, 1);
892 static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
895 *sdl_blendmode = SDL_BLENDMODE_NONE;
896 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
897 if (format == AV_PIX_FMT_RGB32 ||
898 format == AV_PIX_FMT_RGB32_1 ||
899 format == AV_PIX_FMT_BGR32 ||
900 format == AV_PIX_FMT_BGR32_1)
901 *sdl_blendmode = SDL_BLENDMODE_BLEND;
902 for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
903 if (format == sdl_texture_format_map[i].format) {
904 *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
910 static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
913 SDL_BlendMode sdl_blendmode;
914 get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
915 if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
917 switch (sdl_pix_fmt) {
918 case SDL_PIXELFORMAT_UNKNOWN:
919 /* This should only happen if we are not using avfilter... */
920 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
921 frame->width, frame->height, frame->format, frame->width, frame->height,
922 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
923 if (*img_convert_ctx != NULL) {
926 if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
927 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
928 0, frame->height, pixels, pitch);
929 SDL_UnlockTexture(*tex);
932 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
936 case SDL_PIXELFORMAT_IYUV:
937 if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
938 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
939 frame->data[1], frame->linesize[1],
940 frame->data[2], frame->linesize[2]);
941 } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) {
942 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0],
943 frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
944 frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
946 av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
951 if (frame->linesize[0] < 0) {
952 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
954 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
961 static void set_sdl_yuv_conversion_mode(AVFrame *frame)
963 #if SDL_VERSION_ATLEAST(2,0,8)
964 SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
965 if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
966 if (frame->color_range == AVCOL_RANGE_JPEG)
967 mode = SDL_YUV_CONVERSION_JPEG;
968 else if (frame->colorspace == AVCOL_SPC_BT709)
969 mode = SDL_YUV_CONVERSION_BT709;
970 else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
971 mode = SDL_YUV_CONVERSION_BT601;
973 SDL_SetYUVConversionMode(mode);
977 static void video_image_display(VideoState *is)
983 vp = frame_queue_peek_last(&is->pictq);
984 if (is->subtitle_st) {
985 if (frame_queue_nb_remaining(&is->subpq) > 0) {
986 sp = frame_queue_peek(&is->subpq);
988 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
993 if (!sp->width || !sp->height) {
994 sp->width = vp->width;
995 sp->height = vp->height;
997 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
1000 for (i = 0; i < sp->sub.num_rects; i++) {
1001 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1003 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
1004 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
1005 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
1006 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
1008 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
1009 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
1010 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
1011 0, NULL, NULL, NULL);
1012 if (!is->sub_convert_ctx) {
1013 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1016 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
1017 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
1018 0, sub_rect->h, pixels, pitch);
1019 SDL_UnlockTexture(is->sub_texture);
1029 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1031 if (!vp->uploaded) {
1032 if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
1035 vp->flip_v = vp->frame->linesize[0] < 0;
1038 set_sdl_yuv_conversion_mode(vp->frame);
1039 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
1040 set_sdl_yuv_conversion_mode(NULL);
1042 #if USE_ONEPASS_SUBTITLE_RENDER
1043 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
1046 double xratio = (double)rect.w / (double)sp->width;
1047 double yratio = (double)rect.h / (double)sp->height;
1048 for (i = 0; i < sp->sub.num_rects; i++) {
1049 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
1050 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
1051 .y = rect.y + sub_rect->y * yratio,
1052 .w = sub_rect->w * xratio,
1053 .h = sub_rect->h * yratio};
1054 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
1060 static inline int compute_mod(int a, int b)
1062 return a < 0 ? a%b + b : a%b;
1065 static void video_audio_display(VideoState *s)
1067 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1068 int ch, channels, h, h2;
1070 int rdft_bits, nb_freq;
1072 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1074 nb_freq = 1 << (rdft_bits - 1);
1076 /* compute display index : center on currently output samples */
1077 channels = s->audio_tgt.channels;
1078 nb_display_channels = channels;
1080 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1082 delay = s->audio_write_buf_size;
1085 /* to be more precise, we take into account the time spent since
1086 the last buffer computation */
1087 if (audio_callback_time) {
1088 time_diff = av_gettime_relative() - audio_callback_time;
1089 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1092 delay += 2 * data_used;
1093 if (delay < data_used)
1096 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1097 if (s->show_mode == SHOW_MODE_WAVES) {
1099 for (i = 0; i < 1000; i += channels) {
1100 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1101 int a = s->sample_array[idx];
1102 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1103 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1104 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1106 if (h < score && (b ^ c) < 0) {
1113 s->last_i_start = i_start;
1115 i_start = s->last_i_start;
1118 if (s->show_mode == SHOW_MODE_WAVES) {
1119 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1121 /* total height for one channel */
1122 h = s->height / nb_display_channels;
1123 /* graph height / 2 */
1125 for (ch = 0; ch < nb_display_channels; ch++) {
1127 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1128 for (x = 0; x < s->width; x++) {
1129 y = (s->sample_array[i] * h2) >> 15;
1136 fill_rectangle(s->xleft + x, ys, 1, y);
1138 if (i >= SAMPLE_ARRAY_SIZE)
1139 i -= SAMPLE_ARRAY_SIZE;
1143 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1145 for (ch = 1; ch < nb_display_channels; ch++) {
1146 y = s->ytop + ch * h;
1147 fill_rectangle(s->xleft, y, s->width, 1);
1150 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1153 nb_display_channels= FFMIN(nb_display_channels, 2);
1154 if (rdft_bits != s->rdft_bits) {
1155 av_rdft_end(s->rdft);
1156 av_free(s->rdft_data);
1157 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1158 s->rdft_bits = rdft_bits;
1159 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1161 if (!s->rdft || !s->rdft_data){
1162 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1163 s->show_mode = SHOW_MODE_WAVES;
1166 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1169 for (ch = 0; ch < nb_display_channels; ch++) {
1170 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1172 for (x = 0; x < 2 * nb_freq; x++) {
1173 double w = (x-nb_freq) * (1.0 / nb_freq);
1174 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1176 if (i >= SAMPLE_ARRAY_SIZE)
1177 i -= SAMPLE_ARRAY_SIZE;
1179 av_rdft_calc(s->rdft, data[ch]);
1181 /* Least efficient way to do this, we should of course
1182 * directly access it but it is more than fast enough. */
1183 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1185 pixels += pitch * s->height;
1186 for (y = 0; y < s->height; y++) {
1187 double w = 1 / sqrt(nb_freq);
1188 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]));
1189 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1194 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1196 SDL_UnlockTexture(s->vis_texture);
1198 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1202 if (s->xpos >= s->width)
1207 static void stream_component_close(VideoState *is, int stream_index)
1209 AVFormatContext *ic = is->ic;
1210 AVCodecParameters *codecpar;
1212 if (stream_index < 0 || stream_index >= ic->nb_streams)
1214 codecpar = ic->streams[stream_index]->codecpar;
1216 switch (codecpar->codec_type) {
1217 case AVMEDIA_TYPE_AUDIO:
1218 decoder_abort(&is->auddec, &is->sampq);
1219 SDL_CloseAudioDevice(audio_dev);
1220 decoder_destroy(&is->auddec);
1221 swr_free(&is->swr_ctx);
1222 av_freep(&is->audio_buf1);
1223 is->audio_buf1_size = 0;
1224 is->audio_buf = NULL;
1227 av_rdft_end(is->rdft);
1228 av_freep(&is->rdft_data);
1233 case AVMEDIA_TYPE_VIDEO:
1234 decoder_abort(&is->viddec, &is->pictq);
1235 decoder_destroy(&is->viddec);
1237 case AVMEDIA_TYPE_SUBTITLE:
1238 decoder_abort(&is->subdec, &is->subpq);
1239 decoder_destroy(&is->subdec);
1245 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1246 switch (codecpar->codec_type) {
1247 case AVMEDIA_TYPE_AUDIO:
1248 is->audio_st = NULL;
1249 is->audio_stream = -1;
1251 case AVMEDIA_TYPE_VIDEO:
1252 is->video_st = NULL;
1253 is->video_stream = -1;
1255 case AVMEDIA_TYPE_SUBTITLE:
1256 is->subtitle_st = NULL;
1257 is->subtitle_stream = -1;
1264 static void stream_close(VideoState *is)
1266 /* XXX: use a special url_shutdown call to abort parse cleanly */
1267 is->abort_request = 1;
1268 SDL_WaitThread(is->read_tid, NULL);
1270 /* close each stream */
1271 if (is->audio_stream >= 0)
1272 stream_component_close(is, is->audio_stream);
1273 if (is->video_stream >= 0)
1274 stream_component_close(is, is->video_stream);
1275 if (is->subtitle_stream >= 0)
1276 stream_component_close(is, is->subtitle_stream);
1278 avformat_close_input(&is->ic);
1280 packet_queue_destroy(&is->videoq);
1281 packet_queue_destroy(&is->audioq);
1282 packet_queue_destroy(&is->subtitleq);
1284 /* free all pictures */
1285 frame_queue_destory(&is->pictq);
1286 frame_queue_destory(&is->sampq);
1287 frame_queue_destory(&is->subpq);
1288 SDL_DestroyCond(is->continue_read_thread);
1289 sws_freeContext(is->img_convert_ctx);
1290 sws_freeContext(is->sub_convert_ctx);
1291 av_free(is->filename);
1292 if (is->vis_texture)
1293 SDL_DestroyTexture(is->vis_texture);
1294 if (is->vid_texture)
1295 SDL_DestroyTexture(is->vid_texture);
1296 if (is->sub_texture)
1297 SDL_DestroyTexture(is->sub_texture);
1301 static void do_exit(VideoState *is)
1307 SDL_DestroyRenderer(renderer);
1309 SDL_DestroyWindow(window);
1312 av_freep(&vfilters_list);
1314 avformat_network_deinit();
1318 av_log(NULL, AV_LOG_QUIET, "%s", "");
1322 static void sigterm_handler(int sig)
1327 static void set_default_window_size(int width, int height, AVRational sar)
1330 int max_width = screen_width ? screen_width : INT_MAX;
1331 int max_height = screen_height ? screen_height : INT_MAX;
1332 if (max_width == INT_MAX && max_height == INT_MAX)
1333 max_height = height;
1334 calculate_display_rect(&rect, 0, 0, max_width, max_height, width, height, sar);
1335 default_width = rect.w;
1336 default_height = rect.h;
1339 static int video_open(VideoState *is)
1343 w = screen_width ? screen_width : default_width;
1344 h = screen_height ? screen_height : default_height;
1347 window_title = input_filename;
1348 SDL_SetWindowTitle(window, window_title);
1350 SDL_SetWindowSize(window, w, h);
1351 SDL_SetWindowPosition(window, screen_left, screen_top);
1353 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1354 SDL_ShowWindow(window);
1362 /* display the current picture, if any */
1363 static void video_display(VideoState *is)
1368 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1369 SDL_RenderClear(renderer);
1370 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1371 video_audio_display(is);
1372 else if (is->video_st)
1373 video_image_display(is);
1374 SDL_RenderPresent(renderer);
1377 static double get_clock(Clock *c)
1379 if (*c->queue_serial != c->serial)
1384 double time = av_gettime_relative() / 1000000.0;
1385 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1389 static void set_clock_at(Clock *c, double pts, int serial, double time)
1392 c->last_updated = time;
1393 c->pts_drift = c->pts - time;
1397 static void set_clock(Clock *c, double pts, int serial)
1399 double time = av_gettime_relative() / 1000000.0;
1400 set_clock_at(c, pts, serial, time);
1403 static void set_clock_speed(Clock *c, double speed)
1405 set_clock(c, get_clock(c), c->serial);
1409 static void init_clock(Clock *c, int *queue_serial)
1413 c->queue_serial = queue_serial;
1414 set_clock(c, NAN, -1);
1417 static void sync_clock_to_slave(Clock *c, Clock *slave)
1419 double clock = get_clock(c);
1420 double slave_clock = get_clock(slave);
1421 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1422 set_clock(c, slave_clock, slave->serial);
1425 static int get_master_sync_type(VideoState *is) {
1426 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1428 return AV_SYNC_VIDEO_MASTER;
1430 return AV_SYNC_AUDIO_MASTER;
1431 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1433 return AV_SYNC_AUDIO_MASTER;
1435 return AV_SYNC_EXTERNAL_CLOCK;
1437 return AV_SYNC_EXTERNAL_CLOCK;
1441 /* get the current master clock value */
1442 static double get_master_clock(VideoState *is)
1446 switch (get_master_sync_type(is)) {
1447 case AV_SYNC_VIDEO_MASTER:
1448 val = get_clock(&is->vidclk);
1450 case AV_SYNC_AUDIO_MASTER:
1451 val = get_clock(&is->audclk);
1454 val = get_clock(&is->extclk);
1460 static void check_external_clock_speed(VideoState *is) {
1461 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1462 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1463 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1464 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1465 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1466 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1468 double speed = is->extclk.speed;
1470 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1474 /* seek in the stream */
1475 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1477 if (!is->seek_req) {
1480 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1482 is->seek_flags |= AVSEEK_FLAG_BYTE;
1484 SDL_CondSignal(is->continue_read_thread);
1488 /* pause or resume the video */
1489 static void stream_toggle_pause(VideoState *is)
1492 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1493 if (is->read_pause_return != AVERROR(ENOSYS)) {
1494 is->vidclk.paused = 0;
1496 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1498 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1499 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1502 static void toggle_pause(VideoState *is)
1504 stream_toggle_pause(is);
1508 static void toggle_mute(VideoState *is)
1510 is->muted = !is->muted;
1513 static void update_volume(VideoState *is, int sign, double step)
1515 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1516 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1517 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1520 static void step_to_next_frame(VideoState *is)
1522 /* if the stream is paused unpause it, then step */
1524 stream_toggle_pause(is);
1528 static double compute_target_delay(double delay, VideoState *is)
1530 double sync_threshold, diff = 0;
1532 /* update delay to follow master synchronisation source */
1533 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1534 /* if video is slave, we try to correct big delays by
1535 duplicating or deleting a frame */
1536 diff = get_clock(&is->vidclk) - get_master_clock(is);
1538 /* skip or repeat frame. We take into account the
1539 delay to compute the threshold. I still don't know
1540 if it is the best guess */
1541 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1542 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1543 if (diff <= -sync_threshold)
1544 delay = FFMAX(0, delay + diff);
1545 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1546 delay = delay + diff;
1547 else if (diff >= sync_threshold)
1552 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1558 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1559 if (vp->serial == nextvp->serial) {
1560 double duration = nextvp->pts - vp->pts;
1561 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1562 return vp->duration;
1570 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1571 /* update current video pts */
1572 set_clock(&is->vidclk, pts, serial);
1573 sync_clock_to_slave(&is->extclk, &is->vidclk);
1576 /* called to display each frame */
1577 static void video_refresh(void *opaque, double *remaining_time)
1579 VideoState *is = opaque;
1584 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1585 check_external_clock_speed(is);
1587 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1588 time = av_gettime_relative() / 1000000.0;
1589 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1591 is->last_vis_time = time;
1593 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1598 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1599 // nothing to do, no picture to display in the queue
1601 double last_duration, duration, delay;
1604 /* dequeue the picture */
1605 lastvp = frame_queue_peek_last(&is->pictq);
1606 vp = frame_queue_peek(&is->pictq);
1608 if (vp->serial != is->videoq.serial) {
1609 frame_queue_next(&is->pictq);
1613 if (lastvp->serial != vp->serial)
1614 is->frame_timer = av_gettime_relative() / 1000000.0;
1619 /* compute nominal last_duration */
1620 last_duration = vp_duration(is, lastvp, vp);
1621 delay = compute_target_delay(last_duration, is);
1623 time= av_gettime_relative()/1000000.0;
1624 if (time < is->frame_timer + delay) {
1625 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1629 is->frame_timer += delay;
1630 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1631 is->frame_timer = time;
1633 SDL_LockMutex(is->pictq.mutex);
1634 if (!isnan(vp->pts))
1635 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1636 SDL_UnlockMutex(is->pictq.mutex);
1638 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1639 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1640 duration = vp_duration(is, vp, nextvp);
1641 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1642 is->frame_drops_late++;
1643 frame_queue_next(&is->pictq);
1648 if (is->subtitle_st) {
1649 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1650 sp = frame_queue_peek(&is->subpq);
1652 if (frame_queue_nb_remaining(&is->subpq) > 1)
1653 sp2 = frame_queue_peek_next(&is->subpq);
1657 if (sp->serial != is->subtitleq.serial
1658 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1659 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1663 for (i = 0; i < sp->sub.num_rects; i++) {
1664 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1668 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1669 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1670 memset(pixels, 0, sub_rect->w << 2);
1671 SDL_UnlockTexture(is->sub_texture);
1675 frame_queue_next(&is->subpq);
1682 frame_queue_next(&is->pictq);
1683 is->force_refresh = 1;
1685 if (is->step && !is->paused)
1686 stream_toggle_pause(is);
1689 /* display picture */
1690 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1693 is->force_refresh = 0;
1695 static int64_t last_time;
1697 int aqsize, vqsize, sqsize;
1700 cur_time = av_gettime_relative();
1701 if (!last_time || (cur_time - last_time) >= 30000) {
1706 aqsize = is->audioq.size;
1708 vqsize = is->videoq.size;
1709 if (is->subtitle_st)
1710 sqsize = is->subtitleq.size;
1712 if (is->audio_st && is->video_st)
1713 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1714 else if (is->video_st)
1715 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1716 else if (is->audio_st)
1717 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1718 av_log(NULL, AV_LOG_INFO,
1719 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1720 get_master_clock(is),
1721 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1723 is->frame_drops_early + is->frame_drops_late,
1727 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1728 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1730 last_time = cur_time;
1735 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1739 #if defined(DEBUG_SYNC)
1740 printf("frame_type=%c pts=%0.3f\n",
1741 av_get_picture_type_char(src_frame->pict_type), pts);
1744 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1747 vp->sar = src_frame->sample_aspect_ratio;
1750 vp->width = src_frame->width;
1751 vp->height = src_frame->height;
1752 vp->format = src_frame->format;
1755 vp->duration = duration;
1757 vp->serial = serial;
1759 set_default_window_size(vp->width, vp->height, vp->sar);
1761 av_frame_move_ref(vp->frame, src_frame);
1762 frame_queue_push(&is->pictq);
1766 static int get_video_frame(VideoState *is, AVFrame *frame)
1770 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1776 if (frame->pts != AV_NOPTS_VALUE)
1777 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1779 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1781 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1782 if (frame->pts != AV_NOPTS_VALUE) {
1783 double diff = dpts - get_master_clock(is);
1784 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1785 diff - is->frame_last_filter_delay < 0 &&
1786 is->viddec.pkt_serial == is->vidclk.serial &&
1787 is->videoq.nb_packets) {
1788 is->frame_drops_early++;
1789 av_frame_unref(frame);
1800 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1801 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1804 int nb_filters = graph->nb_filters;
1805 AVFilterInOut *outputs = NULL, *inputs = NULL;
1808 outputs = avfilter_inout_alloc();
1809 inputs = avfilter_inout_alloc();
1810 if (!outputs || !inputs) {
1811 ret = AVERROR(ENOMEM);
1815 outputs->name = av_strdup("in");
1816 outputs->filter_ctx = source_ctx;
1817 outputs->pad_idx = 0;
1818 outputs->next = NULL;
1820 inputs->name = av_strdup("out");
1821 inputs->filter_ctx = sink_ctx;
1822 inputs->pad_idx = 0;
1823 inputs->next = NULL;
1825 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1828 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1832 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1833 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1834 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1836 ret = avfilter_graph_config(graph, NULL);
1838 avfilter_inout_free(&outputs);
1839 avfilter_inout_free(&inputs);
1843 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1845 enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
1846 char sws_flags_str[512] = "";
1847 char buffersrc_args[256];
1849 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1850 AVCodecParameters *codecpar = is->video_st->codecpar;
1851 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1852 AVDictionaryEntry *e = NULL;
1853 int nb_pix_fmts = 0;
1856 for (i = 0; i < renderer_info.num_texture_formats; i++) {
1857 for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; j++) {
1858 if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
1859 pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
1864 pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
1866 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1867 if (!strcmp(e->key, "sws_flags")) {
1868 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1870 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1872 if (strlen(sws_flags_str))
1873 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1875 graph->scale_sws_opts = av_strdup(sws_flags_str);
1877 snprintf(buffersrc_args, sizeof(buffersrc_args),
1878 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1879 frame->width, frame->height, frame->format,
1880 is->video_st->time_base.num, is->video_st->time_base.den,
1881 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1882 if (fr.num && fr.den)
1883 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1885 if ((ret = avfilter_graph_create_filter(&filt_src,
1886 avfilter_get_by_name("buffer"),
1887 "ffplay_buffer", buffersrc_args, NULL,
1891 ret = avfilter_graph_create_filter(&filt_out,
1892 avfilter_get_by_name("buffersink"),
1893 "ffplay_buffersink", NULL, NULL, graph);
1897 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1900 last_filter = filt_out;
1902 /* Note: this macro adds a filter before the lastly added filter, so the
1903 * processing order of the filters is in reverse */
1904 #define INSERT_FILT(name, arg) do { \
1905 AVFilterContext *filt_ctx; \
1907 ret = avfilter_graph_create_filter(&filt_ctx, \
1908 avfilter_get_by_name(name), \
1909 "ffplay_" name, arg, NULL, graph); \
1913 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1917 last_filter = filt_ctx; \
1921 double theta = get_rotation(is->video_st);
1923 if (fabs(theta - 90) < 1.0) {
1924 INSERT_FILT("transpose", "clock");
1925 } else if (fabs(theta - 180) < 1.0) {
1926 INSERT_FILT("hflip", NULL);
1927 INSERT_FILT("vflip", NULL);
1928 } else if (fabs(theta - 270) < 1.0) {
1929 INSERT_FILT("transpose", "cclock");
1930 } else if (fabs(theta) > 1.0) {
1931 char rotate_buf[64];
1932 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1933 INSERT_FILT("rotate", rotate_buf);
1937 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1940 is->in_video_filter = filt_src;
1941 is->out_video_filter = filt_out;
1947 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1949 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1950 int sample_rates[2] = { 0, -1 };
1951 int64_t channel_layouts[2] = { 0, -1 };
1952 int channels[2] = { 0, -1 };
1953 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1954 char aresample_swr_opts[512] = "";
1955 AVDictionaryEntry *e = NULL;
1956 char asrc_args[256];
1959 avfilter_graph_free(&is->agraph);
1960 if (!(is->agraph = avfilter_graph_alloc()))
1961 return AVERROR(ENOMEM);
1962 is->agraph->nb_threads = filter_nbthreads;
1964 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1965 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1966 if (strlen(aresample_swr_opts))
1967 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1968 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1970 ret = snprintf(asrc_args, sizeof(asrc_args),
1971 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1972 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1973 is->audio_filter_src.channels,
1974 1, is->audio_filter_src.freq);
1975 if (is->audio_filter_src.channel_layout)
1976 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1977 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1979 ret = avfilter_graph_create_filter(&filt_asrc,
1980 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1981 asrc_args, NULL, is->agraph);
1986 ret = avfilter_graph_create_filter(&filt_asink,
1987 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1988 NULL, NULL, is->agraph);
1992 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1994 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1997 if (force_output_format) {
1998 channel_layouts[0] = is->audio_tgt.channel_layout;
1999 channels [0] = is->audio_tgt.channels;
2000 sample_rates [0] = is->audio_tgt.freq;
2001 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2003 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2005 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2007 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2012 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2015 is->in_audio_filter = filt_asrc;
2016 is->out_audio_filter = filt_asink;
2020 avfilter_graph_free(&is->agraph);
2023 #endif /* CONFIG_AVFILTER */
2025 static int audio_thread(void *arg)
2027 VideoState *is = arg;
2028 AVFrame *frame = av_frame_alloc();
2031 int last_serial = -1;
2032 int64_t dec_channel_layout;
2040 return AVERROR(ENOMEM);
2043 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2047 tb = (AVRational){1, frame->sample_rate};
2050 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
2053 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2054 frame->format, frame->channels) ||
2055 is->audio_filter_src.channel_layout != dec_channel_layout ||
2056 is->audio_filter_src.freq != frame->sample_rate ||
2057 is->auddec.pkt_serial != last_serial;
2060 char buf1[1024], buf2[1024];
2061 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2062 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2063 av_log(NULL, AV_LOG_DEBUG,
2064 "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",
2065 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2066 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2068 is->audio_filter_src.fmt = frame->format;
2069 is->audio_filter_src.channels = frame->channels;
2070 is->audio_filter_src.channel_layout = dec_channel_layout;
2071 is->audio_filter_src.freq = frame->sample_rate;
2072 last_serial = is->auddec.pkt_serial;
2074 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2078 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2081 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2082 tb = av_buffersink_get_time_base(is->out_audio_filter);
2084 if (!(af = frame_queue_peek_writable(&is->sampq)))
2087 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2088 af->pos = frame->pkt_pos;
2089 af->serial = is->auddec.pkt_serial;
2090 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2092 av_frame_move_ref(af->frame, frame);
2093 frame_queue_push(&is->sampq);
2096 if (is->audioq.serial != is->auddec.pkt_serial)
2099 if (ret == AVERROR_EOF)
2100 is->auddec.finished = is->auddec.pkt_serial;
2103 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2106 avfilter_graph_free(&is->agraph);
2108 av_frame_free(&frame);
2112 static int decoder_start(Decoder *d, int (*fn)(void *), const char *thread_name, void* arg)
2114 packet_queue_start(d->queue);
2115 d->decoder_tid = SDL_CreateThread(fn, thread_name, arg);
2116 if (!d->decoder_tid) {
2117 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2118 return AVERROR(ENOMEM);
2123 static int video_thread(void *arg)
2125 VideoState *is = arg;
2126 AVFrame *frame = av_frame_alloc();
2130 AVRational tb = is->video_st->time_base;
2131 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2134 AVFilterGraph *graph = NULL;
2135 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2138 enum AVPixelFormat last_format = -2;
2139 int last_serial = -1;
2140 int last_vfilter_idx = 0;
2144 return AVERROR(ENOMEM);
2147 ret = get_video_frame(is, frame);
2154 if ( last_w != frame->width
2155 || last_h != frame->height
2156 || last_format != frame->format
2157 || last_serial != is->viddec.pkt_serial
2158 || last_vfilter_idx != is->vfilter_idx) {
2159 av_log(NULL, AV_LOG_DEBUG,
2160 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2162 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2163 frame->width, frame->height,
2164 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2165 avfilter_graph_free(&graph);
2166 graph = avfilter_graph_alloc();
2168 ret = AVERROR(ENOMEM);
2171 graph->nb_threads = filter_nbthreads;
2172 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2174 event.type = FF_QUIT_EVENT;
2175 event.user.data1 = is;
2176 SDL_PushEvent(&event);
2179 filt_in = is->in_video_filter;
2180 filt_out = is->out_video_filter;
2181 last_w = frame->width;
2182 last_h = frame->height;
2183 last_format = frame->format;
2184 last_serial = is->viddec.pkt_serial;
2185 last_vfilter_idx = is->vfilter_idx;
2186 frame_rate = av_buffersink_get_frame_rate(filt_out);
2189 ret = av_buffersrc_add_frame(filt_in, frame);
2194 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2196 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2198 if (ret == AVERROR_EOF)
2199 is->viddec.finished = is->viddec.pkt_serial;
2204 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2205 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2206 is->frame_last_filter_delay = 0;
2207 tb = av_buffersink_get_time_base(filt_out);
2209 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2210 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2211 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2212 av_frame_unref(frame);
2214 if (is->videoq.serial != is->viddec.pkt_serial)
2224 avfilter_graph_free(&graph);
2226 av_frame_free(&frame);
2230 static int subtitle_thread(void *arg)
2232 VideoState *is = arg;
2238 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2241 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2246 if (got_subtitle && sp->sub.format == 0) {
2247 if (sp->sub.pts != AV_NOPTS_VALUE)
2248 pts = sp->sub.pts / (double)AV_TIME_BASE;
2250 sp->serial = is->subdec.pkt_serial;
2251 sp->width = is->subdec.avctx->width;
2252 sp->height = is->subdec.avctx->height;
2255 /* now we can update the picture count */
2256 frame_queue_push(&is->subpq);
2257 } else if (got_subtitle) {
2258 avsubtitle_free(&sp->sub);
2264 /* copy samples for viewing in editor window */
2265 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2269 size = samples_size / sizeof(short);
2271 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2274 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2276 is->sample_array_index += len;
2277 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2278 is->sample_array_index = 0;
2283 /* return the wanted number of samples to get better sync if sync_type is video
2284 * or external master clock */
2285 static int synchronize_audio(VideoState *is, int nb_samples)
2287 int wanted_nb_samples = nb_samples;
2289 /* if not master, then we try to remove or add samples to correct the clock */
2290 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2291 double diff, avg_diff;
2292 int min_nb_samples, max_nb_samples;
2294 diff = get_clock(&is->audclk) - get_master_clock(is);
2296 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2297 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2298 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2299 /* not enough measures to have a correct estimate */
2300 is->audio_diff_avg_count++;
2302 /* estimate the A-V difference */
2303 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2305 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2306 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2307 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2308 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2309 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2311 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2312 diff, avg_diff, wanted_nb_samples - nb_samples,
2313 is->audio_clock, is->audio_diff_threshold);
2316 /* too big difference : may be initial PTS errors, so
2318 is->audio_diff_avg_count = 0;
2319 is->audio_diff_cum = 0;
2323 return wanted_nb_samples;
2327 * Decode one audio frame and return its uncompressed size.
2329 * The processed audio frame is decoded, converted if required, and
2330 * stored in is->audio_buf, with size in bytes given by the return
2333 static int audio_decode_frame(VideoState *is)
2335 int data_size, resampled_data_size;
2336 int64_t dec_channel_layout;
2337 av_unused double audio_clock0;
2338 int wanted_nb_samples;
2346 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2347 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2352 if (!(af = frame_queue_peek_readable(&is->sampq)))
2354 frame_queue_next(&is->sampq);
2355 } while (af->serial != is->audioq.serial);
2357 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2358 af->frame->nb_samples,
2359 af->frame->format, 1);
2361 dec_channel_layout =
2362 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2363 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2364 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2366 if (af->frame->format != is->audio_src.fmt ||
2367 dec_channel_layout != is->audio_src.channel_layout ||
2368 af->frame->sample_rate != is->audio_src.freq ||
2369 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2370 swr_free(&is->swr_ctx);
2371 is->swr_ctx = swr_alloc_set_opts(NULL,
2372 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2373 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2375 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2376 av_log(NULL, AV_LOG_ERROR,
2377 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2378 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2379 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2380 swr_free(&is->swr_ctx);
2383 is->audio_src.channel_layout = dec_channel_layout;
2384 is->audio_src.channels = af->frame->channels;
2385 is->audio_src.freq = af->frame->sample_rate;
2386 is->audio_src.fmt = af->frame->format;
2390 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2391 uint8_t **out = &is->audio_buf1;
2392 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2393 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2396 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2399 if (wanted_nb_samples != af->frame->nb_samples) {
2400 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2401 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2402 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2406 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2407 if (!is->audio_buf1)
2408 return AVERROR(ENOMEM);
2409 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2411 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2414 if (len2 == out_count) {
2415 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2416 if (swr_init(is->swr_ctx) < 0)
2417 swr_free(&is->swr_ctx);
2419 is->audio_buf = is->audio_buf1;
2420 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2422 is->audio_buf = af->frame->data[0];
2423 resampled_data_size = data_size;
2426 audio_clock0 = is->audio_clock;
2427 /* update the audio clock with the pts */
2428 if (!isnan(af->pts))
2429 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2431 is->audio_clock = NAN;
2432 is->audio_clock_serial = af->serial;
2435 static double last_clock;
2436 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2437 is->audio_clock - last_clock,
2438 is->audio_clock, audio_clock0);
2439 last_clock = is->audio_clock;
2442 return resampled_data_size;
2445 /* prepare a new audio buffer */
2446 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2448 VideoState *is = opaque;
2449 int audio_size, len1;
2451 audio_callback_time = av_gettime_relative();
2454 if (is->audio_buf_index >= is->audio_buf_size) {
2455 audio_size = audio_decode_frame(is);
2456 if (audio_size < 0) {
2457 /* if error, just output silence */
2458 is->audio_buf = NULL;
2459 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2461 if (is->show_mode != SHOW_MODE_VIDEO)
2462 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2463 is->audio_buf_size = audio_size;
2465 is->audio_buf_index = 0;
2467 len1 = is->audio_buf_size - is->audio_buf_index;
2470 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2471 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2473 memset(stream, 0, len1);
2474 if (!is->muted && is->audio_buf)
2475 SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
2479 is->audio_buf_index += len1;
2481 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2482 /* Let's assume the audio driver that is used by SDL has two periods. */
2483 if (!isnan(is->audio_clock)) {
2484 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);
2485 sync_clock_to_slave(&is->extclk, &is->audclk);
2489 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2491 SDL_AudioSpec wanted_spec, spec;
2493 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2494 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2495 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2497 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2499 wanted_nb_channels = atoi(env);
2500 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2502 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2503 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2504 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2506 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2507 wanted_spec.channels = wanted_nb_channels;
2508 wanted_spec.freq = wanted_sample_rate;
2509 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2510 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2513 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2514 next_sample_rate_idx--;
2515 wanted_spec.format = AUDIO_S16SYS;
2516 wanted_spec.silence = 0;
2517 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2518 wanted_spec.callback = sdl_audio_callback;
2519 wanted_spec.userdata = opaque;
2520 while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
2521 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2522 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2523 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2524 if (!wanted_spec.channels) {
2525 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2526 wanted_spec.channels = wanted_nb_channels;
2527 if (!wanted_spec.freq) {
2528 av_log(NULL, AV_LOG_ERROR,
2529 "No more combinations to try, audio open failed\n");
2533 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2535 if (spec.format != AUDIO_S16SYS) {
2536 av_log(NULL, AV_LOG_ERROR,
2537 "SDL advised audio format %d is not supported!\n", spec.format);
2540 if (spec.channels != wanted_spec.channels) {
2541 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2542 if (!wanted_channel_layout) {
2543 av_log(NULL, AV_LOG_ERROR,
2544 "SDL advised channel count %d is not supported!\n", spec.channels);
2549 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2550 audio_hw_params->freq = spec.freq;
2551 audio_hw_params->channel_layout = wanted_channel_layout;
2552 audio_hw_params->channels = spec.channels;
2553 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2554 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);
2555 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2556 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2562 /* open a given stream. Return 0 if OK */
2563 static int stream_component_open(VideoState *is, int stream_index)
2565 AVFormatContext *ic = is->ic;
2566 AVCodecContext *avctx;
2568 const char *forced_codec_name = NULL;
2569 AVDictionary *opts = NULL;
2570 AVDictionaryEntry *t = NULL;
2571 int sample_rate, nb_channels;
2572 int64_t channel_layout;
2574 int stream_lowres = lowres;
2576 if (stream_index < 0 || stream_index >= ic->nb_streams)
2579 avctx = avcodec_alloc_context3(NULL);
2581 return AVERROR(ENOMEM);
2583 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2586 avctx->pkt_timebase = ic->streams[stream_index]->time_base;
2588 codec = avcodec_find_decoder(avctx->codec_id);
2590 switch(avctx->codec_type){
2591 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2592 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2593 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2595 if (forced_codec_name)
2596 codec = avcodec_find_decoder_by_name(forced_codec_name);
2598 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2599 "No codec could be found with name '%s'\n", forced_codec_name);
2600 else av_log(NULL, AV_LOG_WARNING,
2601 "No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
2602 ret = AVERROR(EINVAL);
2606 avctx->codec_id = codec->id;
2607 if (stream_lowres > codec->max_lowres) {
2608 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2610 stream_lowres = codec->max_lowres;
2612 avctx->lowres = stream_lowres;
2615 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2617 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2618 if (!av_dict_get(opts, "threads", NULL, 0))
2619 av_dict_set(&opts, "threads", "auto", 0);
2621 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2622 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2623 av_dict_set(&opts, "refcounted_frames", "1", 0);
2624 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2627 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2628 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2629 ret = AVERROR_OPTION_NOT_FOUND;
2634 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2635 switch (avctx->codec_type) {
2636 case AVMEDIA_TYPE_AUDIO:
2639 AVFilterContext *sink;
2641 is->audio_filter_src.freq = avctx->sample_rate;
2642 is->audio_filter_src.channels = avctx->channels;
2643 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2644 is->audio_filter_src.fmt = avctx->sample_fmt;
2645 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2647 sink = is->out_audio_filter;
2648 sample_rate = av_buffersink_get_sample_rate(sink);
2649 nb_channels = av_buffersink_get_channels(sink);
2650 channel_layout = av_buffersink_get_channel_layout(sink);
2653 sample_rate = avctx->sample_rate;
2654 nb_channels = avctx->channels;
2655 channel_layout = avctx->channel_layout;
2658 /* prepare audio output */
2659 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2661 is->audio_hw_buf_size = ret;
2662 is->audio_src = is->audio_tgt;
2663 is->audio_buf_size = 0;
2664 is->audio_buf_index = 0;
2666 /* init averaging filter */
2667 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2668 is->audio_diff_avg_count = 0;
2669 /* since we do not have a precise anough audio FIFO fullness,
2670 we correct audio sync only if larger than this threshold */
2671 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2673 is->audio_stream = stream_index;
2674 is->audio_st = ic->streams[stream_index];
2676 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2677 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2678 is->auddec.start_pts = is->audio_st->start_time;
2679 is->auddec.start_pts_tb = is->audio_st->time_base;
2681 if ((ret = decoder_start(&is->auddec, audio_thread, "audio_decoder", is)) < 0)
2683 SDL_PauseAudioDevice(audio_dev, 0);
2685 case AVMEDIA_TYPE_VIDEO:
2686 is->video_stream = stream_index;
2687 is->video_st = ic->streams[stream_index];
2689 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2690 if ((ret = decoder_start(&is->viddec, video_thread, "video_decoder", is)) < 0)
2692 is->queue_attachments_req = 1;
2694 case AVMEDIA_TYPE_SUBTITLE:
2695 is->subtitle_stream = stream_index;
2696 is->subtitle_st = ic->streams[stream_index];
2698 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2699 if ((ret = decoder_start(&is->subdec, subtitle_thread, "subtitle_decoder", is)) < 0)
2708 avcodec_free_context(&avctx);
2710 av_dict_free(&opts);
2715 static int decode_interrupt_cb(void *ctx)
2717 VideoState *is = ctx;
2718 return is->abort_request;
2721 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2722 return stream_id < 0 ||
2723 queue->abort_request ||
2724 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2725 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2728 static int is_realtime(AVFormatContext *s)
2730 if( !strcmp(s->iformat->name, "rtp")
2731 || !strcmp(s->iformat->name, "rtsp")
2732 || !strcmp(s->iformat->name, "sdp")
2736 if(s->pb && ( !strncmp(s->url, "rtp:", 4)
2737 || !strncmp(s->url, "udp:", 4)
2744 /* this thread gets the stream from the disk or the network */
2745 static int read_thread(void *arg)
2747 VideoState *is = arg;
2748 AVFormatContext *ic = NULL;
2750 int st_index[AVMEDIA_TYPE_NB];
2751 AVPacket pkt1, *pkt = &pkt1;
2752 int64_t stream_start_time;
2753 int pkt_in_play_range = 0;
2754 AVDictionaryEntry *t;
2755 SDL_mutex *wait_mutex = SDL_CreateMutex();
2756 int scan_all_pmts_set = 0;
2760 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2761 ret = AVERROR(ENOMEM);
2765 memset(st_index, -1, sizeof(st_index));
2766 is->last_video_stream = is->video_stream = -1;
2767 is->last_audio_stream = is->audio_stream = -1;
2768 is->last_subtitle_stream = is->subtitle_stream = -1;
2771 ic = avformat_alloc_context();
2773 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2774 ret = AVERROR(ENOMEM);
2777 ic->interrupt_callback.callback = decode_interrupt_cb;
2778 ic->interrupt_callback.opaque = is;
2779 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2780 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2781 scan_all_pmts_set = 1;
2783 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2785 print_error(is->filename, err);
2789 if (scan_all_pmts_set)
2790 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2792 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2793 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2794 ret = AVERROR_OPTION_NOT_FOUND;
2800 ic->flags |= AVFMT_FLAG_GENPTS;
2802 av_format_inject_global_side_data(ic);
2804 if (find_stream_info) {
2805 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2806 int orig_nb_streams = ic->nb_streams;
2808 err = avformat_find_stream_info(ic, opts);
2810 for (i = 0; i < orig_nb_streams; i++)
2811 av_dict_free(&opts[i]);
2815 av_log(NULL, AV_LOG_WARNING,
2816 "%s: could not find codec parameters\n", is->filename);
2823 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2825 if (seek_by_bytes < 0)
2826 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2828 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2830 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2831 window_title = av_asprintf("%s - %s", t->value, input_filename);
2833 /* if seeking requested, we execute it */
2834 if (start_time != AV_NOPTS_VALUE) {
2837 timestamp = start_time;
2838 /* add the stream start time */
2839 if (ic->start_time != AV_NOPTS_VALUE)
2840 timestamp += ic->start_time;
2841 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2843 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2844 is->filename, (double)timestamp / AV_TIME_BASE);
2848 is->realtime = is_realtime(ic);
2851 av_dump_format(ic, 0, is->filename, 0);
2853 for (i = 0; i < ic->nb_streams; i++) {
2854 AVStream *st = ic->streams[i];
2855 enum AVMediaType type = st->codecpar->codec_type;
2856 st->discard = AVDISCARD_ALL;
2857 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2858 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2861 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2862 if (wanted_stream_spec[i] && st_index[i] == -1) {
2863 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));
2864 st_index[i] = INT_MAX;
2869 st_index[AVMEDIA_TYPE_VIDEO] =
2870 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2871 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2873 st_index[AVMEDIA_TYPE_AUDIO] =
2874 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2875 st_index[AVMEDIA_TYPE_AUDIO],
2876 st_index[AVMEDIA_TYPE_VIDEO],
2878 if (!video_disable && !subtitle_disable)
2879 st_index[AVMEDIA_TYPE_SUBTITLE] =
2880 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2881 st_index[AVMEDIA_TYPE_SUBTITLE],
2882 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2883 st_index[AVMEDIA_TYPE_AUDIO] :
2884 st_index[AVMEDIA_TYPE_VIDEO]),
2887 is->show_mode = show_mode;
2888 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2889 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2890 AVCodecParameters *codecpar = st->codecpar;
2891 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2892 if (codecpar->width)
2893 set_default_window_size(codecpar->width, codecpar->height, sar);
2896 /* open the streams */
2897 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2898 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2902 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2903 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2905 if (is->show_mode == SHOW_MODE_NONE)
2906 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2908 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2909 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2912 if (is->video_stream < 0 && is->audio_stream < 0) {
2913 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2919 if (infinite_buffer < 0 && is->realtime)
2920 infinite_buffer = 1;
2923 if (is->abort_request)
2925 if (is->paused != is->last_paused) {
2926 is->last_paused = is->paused;
2928 is->read_pause_return = av_read_pause(ic);
2932 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2934 (!strcmp(ic->iformat->name, "rtsp") ||
2935 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2936 /* wait 10 ms to avoid trying to get another packet */
2943 int64_t seek_target = is->seek_pos;
2944 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2945 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2946 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2947 // of the seek_pos/seek_rel variables
2949 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2951 av_log(NULL, AV_LOG_ERROR,
2952 "%s: error while seeking\n", is->ic->url);
2954 if (is->audio_stream >= 0) {
2955 packet_queue_flush(&is->audioq);
2956 packet_queue_put(&is->audioq, &flush_pkt);
2958 if (is->subtitle_stream >= 0) {
2959 packet_queue_flush(&is->subtitleq);
2960 packet_queue_put(&is->subtitleq, &flush_pkt);
2962 if (is->video_stream >= 0) {
2963 packet_queue_flush(&is->videoq);
2964 packet_queue_put(&is->videoq, &flush_pkt);
2966 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2967 set_clock(&is->extclk, NAN, 0);
2969 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2973 is->queue_attachments_req = 1;
2976 step_to_next_frame(is);
2978 if (is->queue_attachments_req) {
2979 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2980 AVPacket copy = { 0 };
2981 if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0)
2983 packet_queue_put(&is->videoq, ©);
2984 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2986 is->queue_attachments_req = 0;
2989 /* if the queue are full, no need to read more */
2990 if (infinite_buffer<1 &&
2991 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2992 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2993 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2994 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2996 SDL_LockMutex(wait_mutex);
2997 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2998 SDL_UnlockMutex(wait_mutex);
3002 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3003 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3004 if (loop != 1 && (!loop || --loop)) {
3005 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3006 } else if (autoexit) {
3011 ret = av_read_frame(ic, pkt);
3013 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3014 if (is->video_stream >= 0)
3015 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3016 if (is->audio_stream >= 0)
3017 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3018 if (is->subtitle_stream >= 0)
3019 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3022 if (ic->pb && ic->pb->error)
3024 SDL_LockMutex(wait_mutex);
3025 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3026 SDL_UnlockMutex(wait_mutex);
3031 /* check if packet is in play range specified by user, then queue, otherwise discard */
3032 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3033 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3034 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3035 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3036 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3037 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3038 <= ((double)duration / 1000000);
3039 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3040 packet_queue_put(&is->audioq, pkt);
3041 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3042 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3043 packet_queue_put(&is->videoq, pkt);
3044 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3045 packet_queue_put(&is->subtitleq, pkt);
3047 av_packet_unref(pkt);
3054 avformat_close_input(&ic);
3059 event.type = FF_QUIT_EVENT;
3060 event.user.data1 = is;
3061 SDL_PushEvent(&event);
3063 SDL_DestroyMutex(wait_mutex);
3067 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3071 is = av_mallocz(sizeof(VideoState));
3074 is->filename = av_strdup(filename);
3077 is->iformat = iformat;
3081 /* start video display */
3082 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3084 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3086 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3089 if (packet_queue_init(&is->videoq) < 0 ||
3090 packet_queue_init(&is->audioq) < 0 ||
3091 packet_queue_init(&is->subtitleq) < 0)
3094 if (!(is->continue_read_thread = SDL_CreateCond())) {
3095 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3099 init_clock(&is->vidclk, &is->videoq.serial);
3100 init_clock(&is->audclk, &is->audioq.serial);
3101 init_clock(&is->extclk, &is->extclk.serial);
3102 is->audio_clock_serial = -1;
3103 if (startup_volume < 0)
3104 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3105 if (startup_volume > 100)
3106 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3107 startup_volume = av_clip(startup_volume, 0, 100);
3108 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3109 is->audio_volume = startup_volume;
3111 is->av_sync_type = av_sync_type;
3112 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3113 if (!is->read_tid) {
3114 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3122 static void stream_cycle_channel(VideoState *is, int codec_type)
3124 AVFormatContext *ic = is->ic;
3125 int start_index, stream_index;
3128 AVProgram *p = NULL;
3129 int nb_streams = is->ic->nb_streams;
3131 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3132 start_index = is->last_video_stream;
3133 old_index = is->video_stream;
3134 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3135 start_index = is->last_audio_stream;
3136 old_index = is->audio_stream;
3138 start_index = is->last_subtitle_stream;
3139 old_index = is->subtitle_stream;
3141 stream_index = start_index;
3143 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3144 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3146 nb_streams = p->nb_stream_indexes;
3147 for (start_index = 0; start_index < nb_streams; start_index++)
3148 if (p->stream_index[start_index] == stream_index)
3150 if (start_index == nb_streams)
3152 stream_index = start_index;
3157 if (++stream_index >= nb_streams)
3159 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3162 is->last_subtitle_stream = -1;
3165 if (start_index == -1)
3169 if (stream_index == start_index)
3171 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3172 if (st->codecpar->codec_type == codec_type) {
3173 /* check that parameters are OK */
3174 switch (codec_type) {
3175 case AVMEDIA_TYPE_AUDIO:
3176 if (st->codecpar->sample_rate != 0 &&
3177 st->codecpar->channels != 0)
3180 case AVMEDIA_TYPE_VIDEO:
3181 case AVMEDIA_TYPE_SUBTITLE:
3189 if (p && stream_index != -1)
3190 stream_index = p->stream_index[stream_index];
3191 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3192 av_get_media_type_string(codec_type),
3196 stream_component_close(is, old_index);
3197 stream_component_open(is, stream_index);
3201 static void toggle_full_screen(VideoState *is)
3203 is_full_screen = !is_full_screen;
3204 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3207 static void toggle_audio_display(VideoState *is)
3209 int next = is->show_mode;
3211 next = (next + 1) % SHOW_MODE_NB;
3212 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3213 if (is->show_mode != next) {
3214 is->force_refresh = 1;
3215 is->show_mode = next;
3219 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3220 double remaining_time = 0.0;
3222 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3223 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3227 if (remaining_time > 0.0)
3228 av_usleep((int64_t)(remaining_time * 1000000.0));
3229 remaining_time = REFRESH_RATE;
3230 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3231 video_refresh(is, &remaining_time);
3236 static void seek_chapter(VideoState *is, int incr)
3238 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3241 if (!is->ic->nb_chapters)
3244 /* find the current chapter */
3245 for (i = 0; i < is->ic->nb_chapters; i++) {
3246 AVChapter *ch = is->ic->chapters[i];
3247 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3255 if (i >= is->ic->nb_chapters)
3258 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3259 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3260 AV_TIME_BASE_Q), 0, 0);
3263 /* handle an event sent by the GUI */
3264 static void event_loop(VideoState *cur_stream)
3267 double incr, pos, frac;
3271 refresh_loop_wait_event(cur_stream, &event);
3272 switch (event.type) {
3274 if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
3275 do_exit(cur_stream);
3278 // If we don't yet have a window, skip all key events, because read_thread might still be initializing...
3279 if (!cur_stream->width)
3281 switch (event.key.keysym.sym) {
3283 toggle_full_screen(cur_stream);
3284 cur_stream->force_refresh = 1;
3288 toggle_pause(cur_stream);
3291 toggle_mute(cur_stream);
3293 case SDLK_KP_MULTIPLY:
3295 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3297 case SDLK_KP_DIVIDE:
3299 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3301 case SDLK_s: // S: Step to next frame
3302 step_to_next_frame(cur_stream);
3305 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3308 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3311 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3312 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3313 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3316 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3320 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3321 if (++cur_stream->vfilter_idx >= nb_vfilters)
3322 cur_stream->vfilter_idx = 0;
3324 cur_stream->vfilter_idx = 0;
3325 toggle_audio_display(cur_stream);
3328 toggle_audio_display(cur_stream);
3332 if (cur_stream->ic->nb_chapters <= 1) {
3336 seek_chapter(cur_stream, 1);
3339 if (cur_stream->ic->nb_chapters <= 1) {
3343 seek_chapter(cur_stream, -1);
3346 incr = seek_interval ? -seek_interval : -10.0;
3349 incr = seek_interval ? seek_interval : 10.0;
3357 if (seek_by_bytes) {
3359 if (pos < 0 && cur_stream->video_stream >= 0)
3360 pos = frame_queue_last_pos(&cur_stream->pictq);
3361 if (pos < 0 && cur_stream->audio_stream >= 0)
3362 pos = frame_queue_last_pos(&cur_stream->sampq);
3364 pos = avio_tell(cur_stream->ic->pb);
3365 if (cur_stream->ic->bit_rate)
3366 incr *= cur_stream->ic->bit_rate / 8.0;
3370 stream_seek(cur_stream, pos, incr, 1);
3372 pos = get_master_clock(cur_stream);
3374 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3376 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3377 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3378 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3385 case SDL_MOUSEBUTTONDOWN:
3386 if (exit_on_mousedown) {
3387 do_exit(cur_stream);
3390 if (event.button.button == SDL_BUTTON_LEFT) {
3391 static int64_t last_mouse_left_click = 0;
3392 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3393 toggle_full_screen(cur_stream);
3394 cur_stream->force_refresh = 1;
3395 last_mouse_left_click = 0;
3397 last_mouse_left_click = av_gettime_relative();
3400 case SDL_MOUSEMOTION:
3401 if (cursor_hidden) {
3405 cursor_last_shown = av_gettime_relative();
3406 if (event.type == SDL_MOUSEBUTTONDOWN) {
3407 if (event.button.button != SDL_BUTTON_RIGHT)
3411 if (!(event.motion.state & SDL_BUTTON_RMASK))
3415 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3416 uint64_t size = avio_size(cur_stream->ic->pb);
3417 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3421 int tns, thh, tmm, tss;
3422 tns = cur_stream->ic->duration / 1000000LL;
3424 tmm = (tns % 3600) / 60;
3426 frac = x / cur_stream->width;
3429 mm = (ns % 3600) / 60;
3431 av_log(NULL, AV_LOG_INFO,
3432 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3433 hh, mm, ss, thh, tmm, tss);
3434 ts = frac * cur_stream->ic->duration;
3435 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3436 ts += cur_stream->ic->start_time;
3437 stream_seek(cur_stream, ts, 0, 0);
3440 case SDL_WINDOWEVENT:
3441 switch (event.window.event) {
3442 case SDL_WINDOWEVENT_SIZE_CHANGED:
3443 screen_width = cur_stream->width = event.window.data1;
3444 screen_height = cur_stream->height = event.window.data2;
3445 if (cur_stream->vis_texture) {
3446 SDL_DestroyTexture(cur_stream->vis_texture);
3447 cur_stream->vis_texture = NULL;
3449 case SDL_WINDOWEVENT_EXPOSED:
3450 cur_stream->force_refresh = 1;
3455 do_exit(cur_stream);
3463 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3465 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3466 return opt_default(NULL, "video_size", arg);
3469 static int opt_width(void *optctx, const char *opt, const char *arg)
3471 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3475 static int opt_height(void *optctx, const char *opt, const char *arg)
3477 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3481 static int opt_format(void *optctx, const char *opt, const char *arg)
3483 file_iformat = av_find_input_format(arg);
3484 if (!file_iformat) {
3485 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3486 return AVERROR(EINVAL);
3491 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3493 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3494 return opt_default(NULL, "pixel_format", arg);
3497 static int opt_sync(void *optctx, const char *opt, const char *arg)
3499 if (!strcmp(arg, "audio"))
3500 av_sync_type = AV_SYNC_AUDIO_MASTER;
3501 else if (!strcmp(arg, "video"))
3502 av_sync_type = AV_SYNC_VIDEO_MASTER;
3503 else if (!strcmp(arg, "ext"))
3504 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3506 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3512 static int opt_seek(void *optctx, const char *opt, const char *arg)
3514 start_time = parse_time_or_die(opt, arg, 1);
3518 static int opt_duration(void *optctx, const char *opt, const char *arg)
3520 duration = parse_time_or_die(opt, arg, 1);
3524 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3526 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3527 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3528 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3529 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3533 static void opt_input_file(void *optctx, const char *filename)
3535 if (input_filename) {
3536 av_log(NULL, AV_LOG_FATAL,
3537 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3538 filename, input_filename);
3541 if (!strcmp(filename, "-"))
3543 input_filename = filename;
3546 static int opt_codec(void *optctx, const char *opt, const char *arg)
3548 const char *spec = strchr(opt, ':');
3550 av_log(NULL, AV_LOG_ERROR,
3551 "No media specifier was specified in '%s' in option '%s'\n",
3553 return AVERROR(EINVAL);
3557 case 'a' : audio_codec_name = arg; break;
3558 case 's' : subtitle_codec_name = arg; break;
3559 case 'v' : video_codec_name = arg; break;
3561 av_log(NULL, AV_LOG_ERROR,
3562 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3563 return AVERROR(EINVAL);
3570 static const OptionDef options[] = {
3571 CMDUTILS_COMMON_OPTIONS
3572 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3573 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3574 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3575 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3576 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3577 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3578 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3579 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3580 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3581 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3582 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3583 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3584 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3585 { "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
3586 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3587 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3588 { "alwaysontop", OPT_BOOL, { &alwaysontop }, "window always on top" },
3589 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3590 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3591 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3592 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3593 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3594 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3595 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3596 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3597 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3598 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3599 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3600 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3601 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3602 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3603 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3604 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3605 { "left", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_left }, "set the x position for the left of the window", "x pos" },
3606 { "top", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_top }, "set the y position for the top of the window", "y pos" },
3608 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3609 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3611 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3612 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3613 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3614 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3615 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3616 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3617 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3618 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3619 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3620 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3621 "read and decode the streams to fill missing information with heuristics" },
3622 { "filter_threads", HAS_ARG | OPT_INT | OPT_EXPERT, { &filter_nbthreads }, "number of filter threads per graph" },
3626 static void show_usage(void)
3628 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3629 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3630 av_log(NULL, AV_LOG_INFO, "\n");
3633 void show_help_default(const char *opt, const char *arg)
3635 av_log_set_callback(log_callback_help);
3637 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3638 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3640 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3641 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3642 #if !CONFIG_AVFILTER
3643 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3645 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3647 printf("\nWhile playing:\n"
3649 "f toggle full screen\n"
3652 "9, 0 decrease and increase volume respectively\n"
3653 "/, * decrease and increase volume respectively\n"
3654 "a cycle audio channel in the current program\n"
3655 "v cycle video channel\n"
3656 "t cycle subtitle channel in the current program\n"
3658 "w cycle video filters or show modes\n"
3659 "s activate frame-step mode\n"
3660 "left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
3661 "down/up seek backward/forward 1 minute\n"
3662 "page down/page up seek backward/forward 10 minutes\n"
3663 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3664 "left double-click toggle full screen\n"
3668 /* Called from the main */
3669 int main(int argc, char **argv)
3676 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3677 parse_loglevel(argc, argv, options);
3679 /* register all codecs, demux and protocols */
3681 avdevice_register_all();
3683 avformat_network_init();
3687 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3688 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3690 show_banner(argc, argv, options);
3692 parse_options(NULL, argc, argv, options, opt_input_file);
3694 if (!input_filename) {
3696 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3697 av_log(NULL, AV_LOG_FATAL,
3698 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3702 if (display_disable) {
3705 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3707 flags &= ~SDL_INIT_AUDIO;
3709 /* Try to work around an occasional ALSA buffer underflow issue when the
3710 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3711 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3712 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3714 if (display_disable)
3715 flags &= ~SDL_INIT_VIDEO;
3716 if (SDL_Init (flags)) {
3717 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3718 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3722 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3723 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3725 av_init_packet(&flush_pkt);
3726 flush_pkt.data = (uint8_t *)&flush_pkt;
3728 if (!display_disable) {
3729 int flags = SDL_WINDOW_HIDDEN;
3731 #if SDL_VERSION_ATLEAST(2,0,5)
3732 flags |= SDL_WINDOW_ALWAYS_ON_TOP;
3734 av_log(NULL, AV_LOG_WARNING, "Your SDL version doesn't support SDL_WINDOW_ALWAYS_ON_TOP. Feature will be inactive.\n");
3737 flags |= SDL_WINDOW_BORDERLESS;
3739 flags |= SDL_WINDOW_RESIZABLE;
3740 window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
3741 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
3743 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
3745 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
3746 renderer = SDL_CreateRenderer(window, -1, 0);
3749 if (!SDL_GetRendererInfo(renderer, &renderer_info))
3750 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
3753 if (!window || !renderer || !renderer_info.num_texture_formats) {
3754 av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
3759 is = stream_open(input_filename, file_iformat);
3761 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");