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 startup_volume = 100;
328 static int show_status = 1;
329 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
330 static int64_t start_time = AV_NOPTS_VALUE;
331 static int64_t duration = AV_NOPTS_VALUE;
333 static int genpts = 0;
334 static int lowres = 0;
335 static int decoder_reorder_pts = -1;
337 static int exit_on_keydown;
338 static int exit_on_mousedown;
340 static int framedrop = -1;
341 static int infinite_buffer = -1;
342 static enum ShowMode show_mode = SHOW_MODE_NONE;
343 static const char *audio_codec_name;
344 static const char *subtitle_codec_name;
345 static const char *video_codec_name;
346 double rdftspeed = 0.02;
347 static int64_t cursor_last_shown;
348 static int cursor_hidden = 0;
350 static const char **vfilters_list = NULL;
351 static int nb_vfilters = 0;
352 static char *afilters = NULL;
354 static int autorotate = 1;
355 static int find_stream_info = 1;
356 static int filter_nbthreads = 0;
358 /* current context */
359 static int is_full_screen;
360 static int64_t audio_callback_time;
362 static AVPacket flush_pkt;
364 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
366 static SDL_Window *window;
367 static SDL_Renderer *renderer;
368 static SDL_RendererInfo renderer_info = {0};
369 static SDL_AudioDeviceID audio_dev;
371 static const struct TextureFormatEntry {
372 enum AVPixelFormat format;
374 } sdl_texture_format_map[] = {
375 { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 },
376 { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 },
377 { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 },
378 { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 },
379 { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 },
380 { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 },
381 { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 },
382 { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 },
383 { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 },
384 { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 },
385 { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 },
386 { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 },
387 { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 },
388 { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 },
389 { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 },
390 { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 },
391 { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV },
392 { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 },
393 { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY },
394 { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN },
398 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
400 GROW_ARRAY(vfilters_list, nb_vfilters);
401 vfilters_list[nb_vfilters - 1] = arg;
407 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
408 enum AVSampleFormat fmt2, int64_t channel_count2)
410 /* If channel count == 1, planar and non-planar formats are the same */
411 if (channel_count1 == 1 && channel_count2 == 1)
412 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
414 return channel_count1 != channel_count2 || fmt1 != fmt2;
418 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
420 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
421 return channel_layout;
426 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
428 MyAVPacketList *pkt1;
430 if (q->abort_request)
433 pkt1 = av_malloc(sizeof(MyAVPacketList));
438 if (pkt == &flush_pkt)
440 pkt1->serial = q->serial;
445 q->last_pkt->next = pkt1;
448 q->size += pkt1->pkt.size + sizeof(*pkt1);
449 q->duration += pkt1->pkt.duration;
450 /* XXX: should duplicate packet data in DV case */
451 SDL_CondSignal(q->cond);
455 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
459 SDL_LockMutex(q->mutex);
460 ret = packet_queue_put_private(q, pkt);
461 SDL_UnlockMutex(q->mutex);
463 if (pkt != &flush_pkt && ret < 0)
464 av_packet_unref(pkt);
469 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
471 AVPacket pkt1, *pkt = &pkt1;
475 pkt->stream_index = stream_index;
476 return packet_queue_put(q, pkt);
479 /* packet queue handling */
480 static int packet_queue_init(PacketQueue *q)
482 memset(q, 0, sizeof(PacketQueue));
483 q->mutex = SDL_CreateMutex();
485 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
486 return AVERROR(ENOMEM);
488 q->cond = SDL_CreateCond();
490 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
491 return AVERROR(ENOMEM);
493 q->abort_request = 1;
497 static void packet_queue_flush(PacketQueue *q)
499 MyAVPacketList *pkt, *pkt1;
501 SDL_LockMutex(q->mutex);
502 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
504 av_packet_unref(&pkt->pkt);
512 SDL_UnlockMutex(q->mutex);
515 static void packet_queue_destroy(PacketQueue *q)
517 packet_queue_flush(q);
518 SDL_DestroyMutex(q->mutex);
519 SDL_DestroyCond(q->cond);
522 static void packet_queue_abort(PacketQueue *q)
524 SDL_LockMutex(q->mutex);
526 q->abort_request = 1;
528 SDL_CondSignal(q->cond);
530 SDL_UnlockMutex(q->mutex);
533 static void packet_queue_start(PacketQueue *q)
535 SDL_LockMutex(q->mutex);
536 q->abort_request = 0;
537 packet_queue_put_private(q, &flush_pkt);
538 SDL_UnlockMutex(q->mutex);
541 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
542 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
544 MyAVPacketList *pkt1;
547 SDL_LockMutex(q->mutex);
550 if (q->abort_request) {
557 q->first_pkt = pkt1->next;
561 q->size -= pkt1->pkt.size + sizeof(*pkt1);
562 q->duration -= pkt1->pkt.duration;
565 *serial = pkt1->serial;
573 SDL_CondWait(q->cond, q->mutex);
576 SDL_UnlockMutex(q->mutex);
580 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
581 memset(d, 0, sizeof(Decoder));
584 d->empty_queue_cond = empty_queue_cond;
585 d->start_pts = AV_NOPTS_VALUE;
589 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
590 int ret = AVERROR(EAGAIN);
595 if (d->queue->serial == d->pkt_serial) {
597 if (d->queue->abort_request)
600 switch (d->avctx->codec_type) {
601 case AVMEDIA_TYPE_VIDEO:
602 ret = avcodec_receive_frame(d->avctx, frame);
604 if (decoder_reorder_pts == -1) {
605 frame->pts = frame->best_effort_timestamp;
606 } else if (!decoder_reorder_pts) {
607 frame->pts = frame->pkt_dts;
611 case AVMEDIA_TYPE_AUDIO:
612 ret = avcodec_receive_frame(d->avctx, frame);
614 AVRational tb = (AVRational){1, frame->sample_rate};
615 if (frame->pts != AV_NOPTS_VALUE)
616 frame->pts = av_rescale_q(frame->pts, d->avctx->pkt_timebase, tb);
617 else if (d->next_pts != AV_NOPTS_VALUE)
618 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
619 if (frame->pts != AV_NOPTS_VALUE) {
620 d->next_pts = frame->pts + frame->nb_samples;
626 if (ret == AVERROR_EOF) {
627 d->finished = d->pkt_serial;
628 avcodec_flush_buffers(d->avctx);
633 } while (ret != AVERROR(EAGAIN));
637 if (d->queue->nb_packets == 0)
638 SDL_CondSignal(d->empty_queue_cond);
639 if (d->packet_pending) {
640 av_packet_move_ref(&pkt, &d->pkt);
641 d->packet_pending = 0;
643 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
646 } while (d->queue->serial != d->pkt_serial);
648 if (pkt.data == flush_pkt.data) {
649 avcodec_flush_buffers(d->avctx);
651 d->next_pts = d->start_pts;
652 d->next_pts_tb = d->start_pts_tb;
654 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
656 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
658 ret = AVERROR(EAGAIN);
660 if (got_frame && !pkt.data) {
661 d->packet_pending = 1;
662 av_packet_move_ref(&d->pkt, &pkt);
664 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
667 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
668 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
669 d->packet_pending = 1;
670 av_packet_move_ref(&d->pkt, &pkt);
673 av_packet_unref(&pkt);
678 static void decoder_destroy(Decoder *d) {
679 av_packet_unref(&d->pkt);
680 avcodec_free_context(&d->avctx);
683 static void frame_queue_unref_item(Frame *vp)
685 av_frame_unref(vp->frame);
686 avsubtitle_free(&vp->sub);
689 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
692 memset(f, 0, sizeof(FrameQueue));
693 if (!(f->mutex = SDL_CreateMutex())) {
694 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
695 return AVERROR(ENOMEM);
697 if (!(f->cond = SDL_CreateCond())) {
698 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
699 return AVERROR(ENOMEM);
702 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
703 f->keep_last = !!keep_last;
704 for (i = 0; i < f->max_size; i++)
705 if (!(f->queue[i].frame = av_frame_alloc()))
706 return AVERROR(ENOMEM);
710 static void frame_queue_destory(FrameQueue *f)
713 for (i = 0; i < f->max_size; i++) {
714 Frame *vp = &f->queue[i];
715 frame_queue_unref_item(vp);
716 av_frame_free(&vp->frame);
718 SDL_DestroyMutex(f->mutex);
719 SDL_DestroyCond(f->cond);
722 static void frame_queue_signal(FrameQueue *f)
724 SDL_LockMutex(f->mutex);
725 SDL_CondSignal(f->cond);
726 SDL_UnlockMutex(f->mutex);
729 static Frame *frame_queue_peek(FrameQueue *f)
731 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
734 static Frame *frame_queue_peek_next(FrameQueue *f)
736 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
739 static Frame *frame_queue_peek_last(FrameQueue *f)
741 return &f->queue[f->rindex];
744 static Frame *frame_queue_peek_writable(FrameQueue *f)
746 /* wait until we have space to put a new frame */
747 SDL_LockMutex(f->mutex);
748 while (f->size >= f->max_size &&
749 !f->pktq->abort_request) {
750 SDL_CondWait(f->cond, f->mutex);
752 SDL_UnlockMutex(f->mutex);
754 if (f->pktq->abort_request)
757 return &f->queue[f->windex];
760 static Frame *frame_queue_peek_readable(FrameQueue *f)
762 /* wait until we have a readable a new frame */
763 SDL_LockMutex(f->mutex);
764 while (f->size - f->rindex_shown <= 0 &&
765 !f->pktq->abort_request) {
766 SDL_CondWait(f->cond, f->mutex);
768 SDL_UnlockMutex(f->mutex);
770 if (f->pktq->abort_request)
773 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
776 static void frame_queue_push(FrameQueue *f)
778 if (++f->windex == f->max_size)
780 SDL_LockMutex(f->mutex);
782 SDL_CondSignal(f->cond);
783 SDL_UnlockMutex(f->mutex);
786 static void frame_queue_next(FrameQueue *f)
788 if (f->keep_last && !f->rindex_shown) {
792 frame_queue_unref_item(&f->queue[f->rindex]);
793 if (++f->rindex == f->max_size)
795 SDL_LockMutex(f->mutex);
797 SDL_CondSignal(f->cond);
798 SDL_UnlockMutex(f->mutex);
801 /* return the number of undisplayed frames in the queue */
802 static int frame_queue_nb_remaining(FrameQueue *f)
804 return f->size - f->rindex_shown;
807 /* return last shown position */
808 static int64_t frame_queue_last_pos(FrameQueue *f)
810 Frame *fp = &f->queue[f->rindex];
811 if (f->rindex_shown && fp->serial == f->pktq->serial)
817 static void decoder_abort(Decoder *d, FrameQueue *fq)
819 packet_queue_abort(d->queue);
820 frame_queue_signal(fq);
821 SDL_WaitThread(d->decoder_tid, NULL);
822 d->decoder_tid = NULL;
823 packet_queue_flush(d->queue);
826 static inline void fill_rectangle(int x, int y, int w, int h)
834 SDL_RenderFillRect(renderer, &rect);
837 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
841 if (!*texture || SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
845 SDL_DestroyTexture(*texture);
846 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
848 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
851 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
853 memset(pixels, 0, pitch * new_height);
854 SDL_UnlockTexture(*texture);
856 av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
861 static void calculate_display_rect(SDL_Rect *rect,
862 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
863 int pic_width, int pic_height, AVRational pic_sar)
865 AVRational aspect_ratio = pic_sar;
866 int64_t width, height, x, y;
868 if (av_cmp_q(aspect_ratio, av_make_q(0, 1)) <= 0)
869 aspect_ratio = av_make_q(1, 1);
871 aspect_ratio = av_mul_q(aspect_ratio, av_make_q(pic_width, pic_height));
873 /* XXX: we suppose the screen has a 1.0 pixel ratio */
875 width = av_rescale(height, aspect_ratio.num, aspect_ratio.den) & ~1;
876 if (width > scr_width) {
878 height = av_rescale(width, aspect_ratio.den, aspect_ratio.num) & ~1;
880 x = (scr_width - width) / 2;
881 y = (scr_height - height) / 2;
882 rect->x = scr_xleft + x;
883 rect->y = scr_ytop + y;
884 rect->w = FFMAX((int)width, 1);
885 rect->h = FFMAX((int)height, 1);
888 static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
891 *sdl_blendmode = SDL_BLENDMODE_NONE;
892 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
893 if (format == AV_PIX_FMT_RGB32 ||
894 format == AV_PIX_FMT_RGB32_1 ||
895 format == AV_PIX_FMT_BGR32 ||
896 format == AV_PIX_FMT_BGR32_1)
897 *sdl_blendmode = SDL_BLENDMODE_BLEND;
898 for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
899 if (format == sdl_texture_format_map[i].format) {
900 *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
906 static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
909 SDL_BlendMode sdl_blendmode;
910 get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
911 if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
913 switch (sdl_pix_fmt) {
914 case SDL_PIXELFORMAT_UNKNOWN:
915 /* This should only happen if we are not using avfilter... */
916 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
917 frame->width, frame->height, frame->format, frame->width, frame->height,
918 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
919 if (*img_convert_ctx != NULL) {
922 if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
923 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
924 0, frame->height, pixels, pitch);
925 SDL_UnlockTexture(*tex);
928 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
932 case SDL_PIXELFORMAT_IYUV:
933 if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
934 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
935 frame->data[1], frame->linesize[1],
936 frame->data[2], frame->linesize[2]);
937 } else 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] * (frame->height - 1), -frame->linesize[0],
939 frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
940 frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
942 av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
947 if (frame->linesize[0] < 0) {
948 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
950 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
957 static void set_sdl_yuv_conversion_mode(AVFrame *frame)
959 #if SDL_VERSION_ATLEAST(2,0,8)
960 SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
961 if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
962 if (frame->color_range == AVCOL_RANGE_JPEG)
963 mode = SDL_YUV_CONVERSION_JPEG;
964 else if (frame->colorspace == AVCOL_SPC_BT709)
965 mode = SDL_YUV_CONVERSION_BT709;
966 else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
967 mode = SDL_YUV_CONVERSION_BT601;
969 SDL_SetYUVConversionMode(mode);
973 static void video_image_display(VideoState *is)
979 vp = frame_queue_peek_last(&is->pictq);
980 if (is->subtitle_st) {
981 if (frame_queue_nb_remaining(&is->subpq) > 0) {
982 sp = frame_queue_peek(&is->subpq);
984 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
989 if (!sp->width || !sp->height) {
990 sp->width = vp->width;
991 sp->height = vp->height;
993 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
996 for (i = 0; i < sp->sub.num_rects; i++) {
997 AVSubtitleRect *sub_rect = sp->sub.rects[i];
999 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
1000 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
1001 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
1002 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
1004 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
1005 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
1006 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
1007 0, NULL, NULL, NULL);
1008 if (!is->sub_convert_ctx) {
1009 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1012 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
1013 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
1014 0, sub_rect->h, pixels, pitch);
1015 SDL_UnlockTexture(is->sub_texture);
1025 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1027 if (!vp->uploaded) {
1028 if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
1031 vp->flip_v = vp->frame->linesize[0] < 0;
1034 set_sdl_yuv_conversion_mode(vp->frame);
1035 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
1036 set_sdl_yuv_conversion_mode(NULL);
1038 #if USE_ONEPASS_SUBTITLE_RENDER
1039 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
1042 double xratio = (double)rect.w / (double)sp->width;
1043 double yratio = (double)rect.h / (double)sp->height;
1044 for (i = 0; i < sp->sub.num_rects; i++) {
1045 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
1046 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
1047 .y = rect.y + sub_rect->y * yratio,
1048 .w = sub_rect->w * xratio,
1049 .h = sub_rect->h * yratio};
1050 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
1056 static inline int compute_mod(int a, int b)
1058 return a < 0 ? a%b + b : a%b;
1061 static void video_audio_display(VideoState *s)
1063 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1064 int ch, channels, h, h2;
1066 int rdft_bits, nb_freq;
1068 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1070 nb_freq = 1 << (rdft_bits - 1);
1072 /* compute display index : center on currently output samples */
1073 channels = s->audio_tgt.channels;
1074 nb_display_channels = channels;
1076 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1078 delay = s->audio_write_buf_size;
1081 /* to be more precise, we take into account the time spent since
1082 the last buffer computation */
1083 if (audio_callback_time) {
1084 time_diff = av_gettime_relative() - audio_callback_time;
1085 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1088 delay += 2 * data_used;
1089 if (delay < data_used)
1092 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1093 if (s->show_mode == SHOW_MODE_WAVES) {
1095 for (i = 0; i < 1000; i += channels) {
1096 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1097 int a = s->sample_array[idx];
1098 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1099 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1100 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1102 if (h < score && (b ^ c) < 0) {
1109 s->last_i_start = i_start;
1111 i_start = s->last_i_start;
1114 if (s->show_mode == SHOW_MODE_WAVES) {
1115 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1117 /* total height for one channel */
1118 h = s->height / nb_display_channels;
1119 /* graph height / 2 */
1121 for (ch = 0; ch < nb_display_channels; ch++) {
1123 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1124 for (x = 0; x < s->width; x++) {
1125 y = (s->sample_array[i] * h2) >> 15;
1132 fill_rectangle(s->xleft + x, ys, 1, y);
1134 if (i >= SAMPLE_ARRAY_SIZE)
1135 i -= SAMPLE_ARRAY_SIZE;
1139 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1141 for (ch = 1; ch < nb_display_channels; ch++) {
1142 y = s->ytop + ch * h;
1143 fill_rectangle(s->xleft, y, s->width, 1);
1146 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1149 nb_display_channels= FFMIN(nb_display_channels, 2);
1150 if (rdft_bits != s->rdft_bits) {
1151 av_rdft_end(s->rdft);
1152 av_free(s->rdft_data);
1153 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1154 s->rdft_bits = rdft_bits;
1155 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1157 if (!s->rdft || !s->rdft_data){
1158 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1159 s->show_mode = SHOW_MODE_WAVES;
1162 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1165 for (ch = 0; ch < nb_display_channels; ch++) {
1166 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1168 for (x = 0; x < 2 * nb_freq; x++) {
1169 double w = (x-nb_freq) * (1.0 / nb_freq);
1170 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1172 if (i >= SAMPLE_ARRAY_SIZE)
1173 i -= SAMPLE_ARRAY_SIZE;
1175 av_rdft_calc(s->rdft, data[ch]);
1177 /* Least efficient way to do this, we should of course
1178 * directly access it but it is more than fast enough. */
1179 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1181 pixels += pitch * s->height;
1182 for (y = 0; y < s->height; y++) {
1183 double w = 1 / sqrt(nb_freq);
1184 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]));
1185 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1190 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1192 SDL_UnlockTexture(s->vis_texture);
1194 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1198 if (s->xpos >= s->width)
1203 static void stream_component_close(VideoState *is, int stream_index)
1205 AVFormatContext *ic = is->ic;
1206 AVCodecParameters *codecpar;
1208 if (stream_index < 0 || stream_index >= ic->nb_streams)
1210 codecpar = ic->streams[stream_index]->codecpar;
1212 switch (codecpar->codec_type) {
1213 case AVMEDIA_TYPE_AUDIO:
1214 decoder_abort(&is->auddec, &is->sampq);
1215 SDL_CloseAudioDevice(audio_dev);
1216 decoder_destroy(&is->auddec);
1217 swr_free(&is->swr_ctx);
1218 av_freep(&is->audio_buf1);
1219 is->audio_buf1_size = 0;
1220 is->audio_buf = NULL;
1223 av_rdft_end(is->rdft);
1224 av_freep(&is->rdft_data);
1229 case AVMEDIA_TYPE_VIDEO:
1230 decoder_abort(&is->viddec, &is->pictq);
1231 decoder_destroy(&is->viddec);
1233 case AVMEDIA_TYPE_SUBTITLE:
1234 decoder_abort(&is->subdec, &is->subpq);
1235 decoder_destroy(&is->subdec);
1241 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1242 switch (codecpar->codec_type) {
1243 case AVMEDIA_TYPE_AUDIO:
1244 is->audio_st = NULL;
1245 is->audio_stream = -1;
1247 case AVMEDIA_TYPE_VIDEO:
1248 is->video_st = NULL;
1249 is->video_stream = -1;
1251 case AVMEDIA_TYPE_SUBTITLE:
1252 is->subtitle_st = NULL;
1253 is->subtitle_stream = -1;
1260 static void stream_close(VideoState *is)
1262 /* XXX: use a special url_shutdown call to abort parse cleanly */
1263 is->abort_request = 1;
1264 SDL_WaitThread(is->read_tid, NULL);
1266 /* close each stream */
1267 if (is->audio_stream >= 0)
1268 stream_component_close(is, is->audio_stream);
1269 if (is->video_stream >= 0)
1270 stream_component_close(is, is->video_stream);
1271 if (is->subtitle_stream >= 0)
1272 stream_component_close(is, is->subtitle_stream);
1274 avformat_close_input(&is->ic);
1276 packet_queue_destroy(&is->videoq);
1277 packet_queue_destroy(&is->audioq);
1278 packet_queue_destroy(&is->subtitleq);
1280 /* free all pictures */
1281 frame_queue_destory(&is->pictq);
1282 frame_queue_destory(&is->sampq);
1283 frame_queue_destory(&is->subpq);
1284 SDL_DestroyCond(is->continue_read_thread);
1285 sws_freeContext(is->img_convert_ctx);
1286 sws_freeContext(is->sub_convert_ctx);
1287 av_free(is->filename);
1288 if (is->vis_texture)
1289 SDL_DestroyTexture(is->vis_texture);
1290 if (is->vid_texture)
1291 SDL_DestroyTexture(is->vid_texture);
1292 if (is->sub_texture)
1293 SDL_DestroyTexture(is->sub_texture);
1297 static void do_exit(VideoState *is)
1303 SDL_DestroyRenderer(renderer);
1305 SDL_DestroyWindow(window);
1308 av_freep(&vfilters_list);
1310 avformat_network_deinit();
1314 av_log(NULL, AV_LOG_QUIET, "%s", "");
1318 static void sigterm_handler(int sig)
1323 static void set_default_window_size(int width, int height, AVRational sar)
1326 int max_width = screen_width ? screen_width : INT_MAX;
1327 int max_height = screen_height ? screen_height : INT_MAX;
1328 if (max_width == INT_MAX && max_height == INT_MAX)
1329 max_height = height;
1330 calculate_display_rect(&rect, 0, 0, max_width, max_height, width, height, sar);
1331 default_width = rect.w;
1332 default_height = rect.h;
1335 static int video_open(VideoState *is)
1339 w = screen_width ? screen_width : default_width;
1340 h = screen_height ? screen_height : default_height;
1343 window_title = input_filename;
1344 SDL_SetWindowTitle(window, window_title);
1346 SDL_SetWindowSize(window, w, h);
1347 SDL_SetWindowPosition(window, screen_left, screen_top);
1349 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1350 SDL_ShowWindow(window);
1358 /* display the current picture, if any */
1359 static void video_display(VideoState *is)
1364 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1365 SDL_RenderClear(renderer);
1366 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1367 video_audio_display(is);
1368 else if (is->video_st)
1369 video_image_display(is);
1370 SDL_RenderPresent(renderer);
1373 static double get_clock(Clock *c)
1375 if (*c->queue_serial != c->serial)
1380 double time = av_gettime_relative() / 1000000.0;
1381 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1385 static void set_clock_at(Clock *c, double pts, int serial, double time)
1388 c->last_updated = time;
1389 c->pts_drift = c->pts - time;
1393 static void set_clock(Clock *c, double pts, int serial)
1395 double time = av_gettime_relative() / 1000000.0;
1396 set_clock_at(c, pts, serial, time);
1399 static void set_clock_speed(Clock *c, double speed)
1401 set_clock(c, get_clock(c), c->serial);
1405 static void init_clock(Clock *c, int *queue_serial)
1409 c->queue_serial = queue_serial;
1410 set_clock(c, NAN, -1);
1413 static void sync_clock_to_slave(Clock *c, Clock *slave)
1415 double clock = get_clock(c);
1416 double slave_clock = get_clock(slave);
1417 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1418 set_clock(c, slave_clock, slave->serial);
1421 static int get_master_sync_type(VideoState *is) {
1422 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1424 return AV_SYNC_VIDEO_MASTER;
1426 return AV_SYNC_AUDIO_MASTER;
1427 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1429 return AV_SYNC_AUDIO_MASTER;
1431 return AV_SYNC_EXTERNAL_CLOCK;
1433 return AV_SYNC_EXTERNAL_CLOCK;
1437 /* get the current master clock value */
1438 static double get_master_clock(VideoState *is)
1442 switch (get_master_sync_type(is)) {
1443 case AV_SYNC_VIDEO_MASTER:
1444 val = get_clock(&is->vidclk);
1446 case AV_SYNC_AUDIO_MASTER:
1447 val = get_clock(&is->audclk);
1450 val = get_clock(&is->extclk);
1456 static void check_external_clock_speed(VideoState *is) {
1457 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1458 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1459 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1460 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1461 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1462 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1464 double speed = is->extclk.speed;
1466 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1470 /* seek in the stream */
1471 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1473 if (!is->seek_req) {
1476 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1478 is->seek_flags |= AVSEEK_FLAG_BYTE;
1480 SDL_CondSignal(is->continue_read_thread);
1484 /* pause or resume the video */
1485 static void stream_toggle_pause(VideoState *is)
1488 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1489 if (is->read_pause_return != AVERROR(ENOSYS)) {
1490 is->vidclk.paused = 0;
1492 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1494 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1495 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1498 static void toggle_pause(VideoState *is)
1500 stream_toggle_pause(is);
1504 static void toggle_mute(VideoState *is)
1506 is->muted = !is->muted;
1509 static void update_volume(VideoState *is, int sign, double step)
1511 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1512 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1513 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1516 static void step_to_next_frame(VideoState *is)
1518 /* if the stream is paused unpause it, then step */
1520 stream_toggle_pause(is);
1524 static double compute_target_delay(double delay, VideoState *is)
1526 double sync_threshold, diff = 0;
1528 /* update delay to follow master synchronisation source */
1529 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1530 /* if video is slave, we try to correct big delays by
1531 duplicating or deleting a frame */
1532 diff = get_clock(&is->vidclk) - get_master_clock(is);
1534 /* skip or repeat frame. We take into account the
1535 delay to compute the threshold. I still don't know
1536 if it is the best guess */
1537 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1538 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1539 if (diff <= -sync_threshold)
1540 delay = FFMAX(0, delay + diff);
1541 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1542 delay = delay + diff;
1543 else if (diff >= sync_threshold)
1548 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1554 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1555 if (vp->serial == nextvp->serial) {
1556 double duration = nextvp->pts - vp->pts;
1557 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1558 return vp->duration;
1566 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1567 /* update current video pts */
1568 set_clock(&is->vidclk, pts, serial);
1569 sync_clock_to_slave(&is->extclk, &is->vidclk);
1572 /* called to display each frame */
1573 static void video_refresh(void *opaque, double *remaining_time)
1575 VideoState *is = opaque;
1580 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1581 check_external_clock_speed(is);
1583 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1584 time = av_gettime_relative() / 1000000.0;
1585 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1587 is->last_vis_time = time;
1589 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1594 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1595 // nothing to do, no picture to display in the queue
1597 double last_duration, duration, delay;
1600 /* dequeue the picture */
1601 lastvp = frame_queue_peek_last(&is->pictq);
1602 vp = frame_queue_peek(&is->pictq);
1604 if (vp->serial != is->videoq.serial) {
1605 frame_queue_next(&is->pictq);
1609 if (lastvp->serial != vp->serial)
1610 is->frame_timer = av_gettime_relative() / 1000000.0;
1615 /* compute nominal last_duration */
1616 last_duration = vp_duration(is, lastvp, vp);
1617 delay = compute_target_delay(last_duration, is);
1619 time= av_gettime_relative()/1000000.0;
1620 if (time < is->frame_timer + delay) {
1621 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1625 is->frame_timer += delay;
1626 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1627 is->frame_timer = time;
1629 SDL_LockMutex(is->pictq.mutex);
1630 if (!isnan(vp->pts))
1631 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1632 SDL_UnlockMutex(is->pictq.mutex);
1634 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1635 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1636 duration = vp_duration(is, vp, nextvp);
1637 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1638 is->frame_drops_late++;
1639 frame_queue_next(&is->pictq);
1644 if (is->subtitle_st) {
1645 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1646 sp = frame_queue_peek(&is->subpq);
1648 if (frame_queue_nb_remaining(&is->subpq) > 1)
1649 sp2 = frame_queue_peek_next(&is->subpq);
1653 if (sp->serial != is->subtitleq.serial
1654 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1655 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1659 for (i = 0; i < sp->sub.num_rects; i++) {
1660 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1664 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1665 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1666 memset(pixels, 0, sub_rect->w << 2);
1667 SDL_UnlockTexture(is->sub_texture);
1671 frame_queue_next(&is->subpq);
1678 frame_queue_next(&is->pictq);
1679 is->force_refresh = 1;
1681 if (is->step && !is->paused)
1682 stream_toggle_pause(is);
1685 /* display picture */
1686 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1689 is->force_refresh = 0;
1691 static int64_t last_time;
1693 int aqsize, vqsize, sqsize;
1696 cur_time = av_gettime_relative();
1697 if (!last_time || (cur_time - last_time) >= 30000) {
1702 aqsize = is->audioq.size;
1704 vqsize = is->videoq.size;
1705 if (is->subtitle_st)
1706 sqsize = is->subtitleq.size;
1708 if (is->audio_st && is->video_st)
1709 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1710 else if (is->video_st)
1711 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1712 else if (is->audio_st)
1713 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1714 av_log(NULL, AV_LOG_INFO,
1715 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1716 get_master_clock(is),
1717 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1719 is->frame_drops_early + is->frame_drops_late,
1723 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1724 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1726 last_time = cur_time;
1731 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1735 #if defined(DEBUG_SYNC)
1736 printf("frame_type=%c pts=%0.3f\n",
1737 av_get_picture_type_char(src_frame->pict_type), pts);
1740 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1743 vp->sar = src_frame->sample_aspect_ratio;
1746 vp->width = src_frame->width;
1747 vp->height = src_frame->height;
1748 vp->format = src_frame->format;
1751 vp->duration = duration;
1753 vp->serial = serial;
1755 set_default_window_size(vp->width, vp->height, vp->sar);
1757 av_frame_move_ref(vp->frame, src_frame);
1758 frame_queue_push(&is->pictq);
1762 static int get_video_frame(VideoState *is, AVFrame *frame)
1766 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1772 if (frame->pts != AV_NOPTS_VALUE)
1773 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1775 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1777 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1778 if (frame->pts != AV_NOPTS_VALUE) {
1779 double diff = dpts - get_master_clock(is);
1780 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1781 diff - is->frame_last_filter_delay < 0 &&
1782 is->viddec.pkt_serial == is->vidclk.serial &&
1783 is->videoq.nb_packets) {
1784 is->frame_drops_early++;
1785 av_frame_unref(frame);
1796 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1797 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1800 int nb_filters = graph->nb_filters;
1801 AVFilterInOut *outputs = NULL, *inputs = NULL;
1804 outputs = avfilter_inout_alloc();
1805 inputs = avfilter_inout_alloc();
1806 if (!outputs || !inputs) {
1807 ret = AVERROR(ENOMEM);
1811 outputs->name = av_strdup("in");
1812 outputs->filter_ctx = source_ctx;
1813 outputs->pad_idx = 0;
1814 outputs->next = NULL;
1816 inputs->name = av_strdup("out");
1817 inputs->filter_ctx = sink_ctx;
1818 inputs->pad_idx = 0;
1819 inputs->next = NULL;
1821 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1824 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1828 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1829 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1830 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1832 ret = avfilter_graph_config(graph, NULL);
1834 avfilter_inout_free(&outputs);
1835 avfilter_inout_free(&inputs);
1839 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1841 enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
1842 char sws_flags_str[512] = "";
1843 char buffersrc_args[256];
1845 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1846 AVCodecParameters *codecpar = is->video_st->codecpar;
1847 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1848 AVDictionaryEntry *e = NULL;
1849 int nb_pix_fmts = 0;
1852 for (i = 0; i < renderer_info.num_texture_formats; i++) {
1853 for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; j++) {
1854 if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
1855 pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
1860 pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
1862 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1863 if (!strcmp(e->key, "sws_flags")) {
1864 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1866 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1868 if (strlen(sws_flags_str))
1869 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1871 graph->scale_sws_opts = av_strdup(sws_flags_str);
1873 snprintf(buffersrc_args, sizeof(buffersrc_args),
1874 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1875 frame->width, frame->height, frame->format,
1876 is->video_st->time_base.num, is->video_st->time_base.den,
1877 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1878 if (fr.num && fr.den)
1879 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1881 if ((ret = avfilter_graph_create_filter(&filt_src,
1882 avfilter_get_by_name("buffer"),
1883 "ffplay_buffer", buffersrc_args, NULL,
1887 ret = avfilter_graph_create_filter(&filt_out,
1888 avfilter_get_by_name("buffersink"),
1889 "ffplay_buffersink", NULL, NULL, graph);
1893 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1896 last_filter = filt_out;
1898 /* Note: this macro adds a filter before the lastly added filter, so the
1899 * processing order of the filters is in reverse */
1900 #define INSERT_FILT(name, arg) do { \
1901 AVFilterContext *filt_ctx; \
1903 ret = avfilter_graph_create_filter(&filt_ctx, \
1904 avfilter_get_by_name(name), \
1905 "ffplay_" name, arg, NULL, graph); \
1909 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1913 last_filter = filt_ctx; \
1917 double theta = get_rotation(is->video_st);
1919 if (fabs(theta - 90) < 1.0) {
1920 INSERT_FILT("transpose", "clock");
1921 } else if (fabs(theta - 180) < 1.0) {
1922 INSERT_FILT("hflip", NULL);
1923 INSERT_FILT("vflip", NULL);
1924 } else if (fabs(theta - 270) < 1.0) {
1925 INSERT_FILT("transpose", "cclock");
1926 } else if (fabs(theta) > 1.0) {
1927 char rotate_buf[64];
1928 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1929 INSERT_FILT("rotate", rotate_buf);
1933 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1936 is->in_video_filter = filt_src;
1937 is->out_video_filter = filt_out;
1943 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1945 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1946 int sample_rates[2] = { 0, -1 };
1947 int64_t channel_layouts[2] = { 0, -1 };
1948 int channels[2] = { 0, -1 };
1949 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1950 char aresample_swr_opts[512] = "";
1951 AVDictionaryEntry *e = NULL;
1952 char asrc_args[256];
1955 avfilter_graph_free(&is->agraph);
1956 if (!(is->agraph = avfilter_graph_alloc()))
1957 return AVERROR(ENOMEM);
1958 is->agraph->nb_threads = filter_nbthreads;
1960 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1961 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1962 if (strlen(aresample_swr_opts))
1963 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1964 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1966 ret = snprintf(asrc_args, sizeof(asrc_args),
1967 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1968 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1969 is->audio_filter_src.channels,
1970 1, is->audio_filter_src.freq);
1971 if (is->audio_filter_src.channel_layout)
1972 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1973 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1975 ret = avfilter_graph_create_filter(&filt_asrc,
1976 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1977 asrc_args, NULL, is->agraph);
1982 ret = avfilter_graph_create_filter(&filt_asink,
1983 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1984 NULL, NULL, is->agraph);
1988 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1990 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1993 if (force_output_format) {
1994 channel_layouts[0] = is->audio_tgt.channel_layout;
1995 channels [0] = is->audio_tgt.channels;
1996 sample_rates [0] = is->audio_tgt.freq;
1997 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1999 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2001 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2003 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2008 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2011 is->in_audio_filter = filt_asrc;
2012 is->out_audio_filter = filt_asink;
2016 avfilter_graph_free(&is->agraph);
2019 #endif /* CONFIG_AVFILTER */
2021 static int audio_thread(void *arg)
2023 VideoState *is = arg;
2024 AVFrame *frame = av_frame_alloc();
2027 int last_serial = -1;
2028 int64_t dec_channel_layout;
2036 return AVERROR(ENOMEM);
2039 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2043 tb = (AVRational){1, frame->sample_rate};
2046 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
2049 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2050 frame->format, frame->channels) ||
2051 is->audio_filter_src.channel_layout != dec_channel_layout ||
2052 is->audio_filter_src.freq != frame->sample_rate ||
2053 is->auddec.pkt_serial != last_serial;
2056 char buf1[1024], buf2[1024];
2057 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2058 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2059 av_log(NULL, AV_LOG_DEBUG,
2060 "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",
2061 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2062 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2064 is->audio_filter_src.fmt = frame->format;
2065 is->audio_filter_src.channels = frame->channels;
2066 is->audio_filter_src.channel_layout = dec_channel_layout;
2067 is->audio_filter_src.freq = frame->sample_rate;
2068 last_serial = is->auddec.pkt_serial;
2070 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2074 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2077 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2078 tb = av_buffersink_get_time_base(is->out_audio_filter);
2080 if (!(af = frame_queue_peek_writable(&is->sampq)))
2083 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2084 af->pos = frame->pkt_pos;
2085 af->serial = is->auddec.pkt_serial;
2086 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2088 av_frame_move_ref(af->frame, frame);
2089 frame_queue_push(&is->sampq);
2092 if (is->audioq.serial != is->auddec.pkt_serial)
2095 if (ret == AVERROR_EOF)
2096 is->auddec.finished = is->auddec.pkt_serial;
2099 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2102 avfilter_graph_free(&is->agraph);
2104 av_frame_free(&frame);
2108 static int decoder_start(Decoder *d, int (*fn)(void *), const char *thread_name, void* arg)
2110 packet_queue_start(d->queue);
2111 d->decoder_tid = SDL_CreateThread(fn, thread_name, arg);
2112 if (!d->decoder_tid) {
2113 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2114 return AVERROR(ENOMEM);
2119 static int video_thread(void *arg)
2121 VideoState *is = arg;
2122 AVFrame *frame = av_frame_alloc();
2126 AVRational tb = is->video_st->time_base;
2127 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2130 AVFilterGraph *graph = NULL;
2131 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2134 enum AVPixelFormat last_format = -2;
2135 int last_serial = -1;
2136 int last_vfilter_idx = 0;
2140 return AVERROR(ENOMEM);
2143 ret = get_video_frame(is, frame);
2150 if ( last_w != frame->width
2151 || last_h != frame->height
2152 || last_format != frame->format
2153 || last_serial != is->viddec.pkt_serial
2154 || last_vfilter_idx != is->vfilter_idx) {
2155 av_log(NULL, AV_LOG_DEBUG,
2156 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2158 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2159 frame->width, frame->height,
2160 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2161 avfilter_graph_free(&graph);
2162 graph = avfilter_graph_alloc();
2164 ret = AVERROR(ENOMEM);
2167 graph->nb_threads = filter_nbthreads;
2168 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2170 event.type = FF_QUIT_EVENT;
2171 event.user.data1 = is;
2172 SDL_PushEvent(&event);
2175 filt_in = is->in_video_filter;
2176 filt_out = is->out_video_filter;
2177 last_w = frame->width;
2178 last_h = frame->height;
2179 last_format = frame->format;
2180 last_serial = is->viddec.pkt_serial;
2181 last_vfilter_idx = is->vfilter_idx;
2182 frame_rate = av_buffersink_get_frame_rate(filt_out);
2185 ret = av_buffersrc_add_frame(filt_in, frame);
2190 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2192 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2194 if (ret == AVERROR_EOF)
2195 is->viddec.finished = is->viddec.pkt_serial;
2200 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2201 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2202 is->frame_last_filter_delay = 0;
2203 tb = av_buffersink_get_time_base(filt_out);
2205 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2206 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2207 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2208 av_frame_unref(frame);
2210 if (is->videoq.serial != is->viddec.pkt_serial)
2220 avfilter_graph_free(&graph);
2222 av_frame_free(&frame);
2226 static int subtitle_thread(void *arg)
2228 VideoState *is = arg;
2234 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2237 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2242 if (got_subtitle && sp->sub.format == 0) {
2243 if (sp->sub.pts != AV_NOPTS_VALUE)
2244 pts = sp->sub.pts / (double)AV_TIME_BASE;
2246 sp->serial = is->subdec.pkt_serial;
2247 sp->width = is->subdec.avctx->width;
2248 sp->height = is->subdec.avctx->height;
2251 /* now we can update the picture count */
2252 frame_queue_push(&is->subpq);
2253 } else if (got_subtitle) {
2254 avsubtitle_free(&sp->sub);
2260 /* copy samples for viewing in editor window */
2261 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2265 size = samples_size / sizeof(short);
2267 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2270 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2272 is->sample_array_index += len;
2273 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2274 is->sample_array_index = 0;
2279 /* return the wanted number of samples to get better sync if sync_type is video
2280 * or external master clock */
2281 static int synchronize_audio(VideoState *is, int nb_samples)
2283 int wanted_nb_samples = nb_samples;
2285 /* if not master, then we try to remove or add samples to correct the clock */
2286 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2287 double diff, avg_diff;
2288 int min_nb_samples, max_nb_samples;
2290 diff = get_clock(&is->audclk) - get_master_clock(is);
2292 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2293 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2294 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2295 /* not enough measures to have a correct estimate */
2296 is->audio_diff_avg_count++;
2298 /* estimate the A-V difference */
2299 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2301 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2302 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2303 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2304 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2305 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2307 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2308 diff, avg_diff, wanted_nb_samples - nb_samples,
2309 is->audio_clock, is->audio_diff_threshold);
2312 /* too big difference : may be initial PTS errors, so
2314 is->audio_diff_avg_count = 0;
2315 is->audio_diff_cum = 0;
2319 return wanted_nb_samples;
2323 * Decode one audio frame and return its uncompressed size.
2325 * The processed audio frame is decoded, converted if required, and
2326 * stored in is->audio_buf, with size in bytes given by the return
2329 static int audio_decode_frame(VideoState *is)
2331 int data_size, resampled_data_size;
2332 int64_t dec_channel_layout;
2333 av_unused double audio_clock0;
2334 int wanted_nb_samples;
2342 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2343 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2348 if (!(af = frame_queue_peek_readable(&is->sampq)))
2350 frame_queue_next(&is->sampq);
2351 } while (af->serial != is->audioq.serial);
2353 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2354 af->frame->nb_samples,
2355 af->frame->format, 1);
2357 dec_channel_layout =
2358 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2359 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2360 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2362 if (af->frame->format != is->audio_src.fmt ||
2363 dec_channel_layout != is->audio_src.channel_layout ||
2364 af->frame->sample_rate != is->audio_src.freq ||
2365 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2366 swr_free(&is->swr_ctx);
2367 is->swr_ctx = swr_alloc_set_opts(NULL,
2368 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2369 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2371 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2372 av_log(NULL, AV_LOG_ERROR,
2373 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2374 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2375 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2376 swr_free(&is->swr_ctx);
2379 is->audio_src.channel_layout = dec_channel_layout;
2380 is->audio_src.channels = af->frame->channels;
2381 is->audio_src.freq = af->frame->sample_rate;
2382 is->audio_src.fmt = af->frame->format;
2386 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2387 uint8_t **out = &is->audio_buf1;
2388 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2389 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2392 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2395 if (wanted_nb_samples != af->frame->nb_samples) {
2396 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2397 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2398 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2402 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2403 if (!is->audio_buf1)
2404 return AVERROR(ENOMEM);
2405 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2407 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2410 if (len2 == out_count) {
2411 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2412 if (swr_init(is->swr_ctx) < 0)
2413 swr_free(&is->swr_ctx);
2415 is->audio_buf = is->audio_buf1;
2416 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2418 is->audio_buf = af->frame->data[0];
2419 resampled_data_size = data_size;
2422 audio_clock0 = is->audio_clock;
2423 /* update the audio clock with the pts */
2424 if (!isnan(af->pts))
2425 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2427 is->audio_clock = NAN;
2428 is->audio_clock_serial = af->serial;
2431 static double last_clock;
2432 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2433 is->audio_clock - last_clock,
2434 is->audio_clock, audio_clock0);
2435 last_clock = is->audio_clock;
2438 return resampled_data_size;
2441 /* prepare a new audio buffer */
2442 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2444 VideoState *is = opaque;
2445 int audio_size, len1;
2447 audio_callback_time = av_gettime_relative();
2450 if (is->audio_buf_index >= is->audio_buf_size) {
2451 audio_size = audio_decode_frame(is);
2452 if (audio_size < 0) {
2453 /* if error, just output silence */
2454 is->audio_buf = NULL;
2455 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2457 if (is->show_mode != SHOW_MODE_VIDEO)
2458 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2459 is->audio_buf_size = audio_size;
2461 is->audio_buf_index = 0;
2463 len1 = is->audio_buf_size - is->audio_buf_index;
2466 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2467 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2469 memset(stream, 0, len1);
2470 if (!is->muted && is->audio_buf)
2471 SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
2475 is->audio_buf_index += len1;
2477 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2478 /* Let's assume the audio driver that is used by SDL has two periods. */
2479 if (!isnan(is->audio_clock)) {
2480 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);
2481 sync_clock_to_slave(&is->extclk, &is->audclk);
2485 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2487 SDL_AudioSpec wanted_spec, spec;
2489 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2490 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2491 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2493 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2495 wanted_nb_channels = atoi(env);
2496 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2498 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2499 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2500 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2502 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2503 wanted_spec.channels = wanted_nb_channels;
2504 wanted_spec.freq = wanted_sample_rate;
2505 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2506 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2509 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2510 next_sample_rate_idx--;
2511 wanted_spec.format = AUDIO_S16SYS;
2512 wanted_spec.silence = 0;
2513 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2514 wanted_spec.callback = sdl_audio_callback;
2515 wanted_spec.userdata = opaque;
2516 while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
2517 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2518 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2519 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2520 if (!wanted_spec.channels) {
2521 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2522 wanted_spec.channels = wanted_nb_channels;
2523 if (!wanted_spec.freq) {
2524 av_log(NULL, AV_LOG_ERROR,
2525 "No more combinations to try, audio open failed\n");
2529 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2531 if (spec.format != AUDIO_S16SYS) {
2532 av_log(NULL, AV_LOG_ERROR,
2533 "SDL advised audio format %d is not supported!\n", spec.format);
2536 if (spec.channels != wanted_spec.channels) {
2537 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2538 if (!wanted_channel_layout) {
2539 av_log(NULL, AV_LOG_ERROR,
2540 "SDL advised channel count %d is not supported!\n", spec.channels);
2545 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2546 audio_hw_params->freq = spec.freq;
2547 audio_hw_params->channel_layout = wanted_channel_layout;
2548 audio_hw_params->channels = spec.channels;
2549 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2550 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);
2551 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2552 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2558 /* open a given stream. Return 0 if OK */
2559 static int stream_component_open(VideoState *is, int stream_index)
2561 AVFormatContext *ic = is->ic;
2562 AVCodecContext *avctx;
2564 const char *forced_codec_name = NULL;
2565 AVDictionary *opts = NULL;
2566 AVDictionaryEntry *t = NULL;
2567 int sample_rate, nb_channels;
2568 int64_t channel_layout;
2570 int stream_lowres = lowres;
2572 if (stream_index < 0 || stream_index >= ic->nb_streams)
2575 avctx = avcodec_alloc_context3(NULL);
2577 return AVERROR(ENOMEM);
2579 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2582 avctx->pkt_timebase = ic->streams[stream_index]->time_base;
2584 codec = avcodec_find_decoder(avctx->codec_id);
2586 switch(avctx->codec_type){
2587 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2588 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2589 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2591 if (forced_codec_name)
2592 codec = avcodec_find_decoder_by_name(forced_codec_name);
2594 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2595 "No codec could be found with name '%s'\n", forced_codec_name);
2596 else av_log(NULL, AV_LOG_WARNING,
2597 "No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
2598 ret = AVERROR(EINVAL);
2602 avctx->codec_id = codec->id;
2603 if (stream_lowres > codec->max_lowres) {
2604 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2606 stream_lowres = codec->max_lowres;
2608 avctx->lowres = stream_lowres;
2611 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2613 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2614 if (!av_dict_get(opts, "threads", NULL, 0))
2615 av_dict_set(&opts, "threads", "auto", 0);
2617 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2618 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2619 av_dict_set(&opts, "refcounted_frames", "1", 0);
2620 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2623 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2624 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2625 ret = AVERROR_OPTION_NOT_FOUND;
2630 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2631 switch (avctx->codec_type) {
2632 case AVMEDIA_TYPE_AUDIO:
2635 AVFilterContext *sink;
2637 is->audio_filter_src.freq = avctx->sample_rate;
2638 is->audio_filter_src.channels = avctx->channels;
2639 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2640 is->audio_filter_src.fmt = avctx->sample_fmt;
2641 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2643 sink = is->out_audio_filter;
2644 sample_rate = av_buffersink_get_sample_rate(sink);
2645 nb_channels = av_buffersink_get_channels(sink);
2646 channel_layout = av_buffersink_get_channel_layout(sink);
2649 sample_rate = avctx->sample_rate;
2650 nb_channels = avctx->channels;
2651 channel_layout = avctx->channel_layout;
2654 /* prepare audio output */
2655 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2657 is->audio_hw_buf_size = ret;
2658 is->audio_src = is->audio_tgt;
2659 is->audio_buf_size = 0;
2660 is->audio_buf_index = 0;
2662 /* init averaging filter */
2663 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2664 is->audio_diff_avg_count = 0;
2665 /* since we do not have a precise anough audio FIFO fullness,
2666 we correct audio sync only if larger than this threshold */
2667 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2669 is->audio_stream = stream_index;
2670 is->audio_st = ic->streams[stream_index];
2672 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2673 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2674 is->auddec.start_pts = is->audio_st->start_time;
2675 is->auddec.start_pts_tb = is->audio_st->time_base;
2677 if ((ret = decoder_start(&is->auddec, audio_thread, "audio_decoder", is)) < 0)
2679 SDL_PauseAudioDevice(audio_dev, 0);
2681 case AVMEDIA_TYPE_VIDEO:
2682 is->video_stream = stream_index;
2683 is->video_st = ic->streams[stream_index];
2685 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2686 if ((ret = decoder_start(&is->viddec, video_thread, "video_decoder", is)) < 0)
2688 is->queue_attachments_req = 1;
2690 case AVMEDIA_TYPE_SUBTITLE:
2691 is->subtitle_stream = stream_index;
2692 is->subtitle_st = ic->streams[stream_index];
2694 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2695 if ((ret = decoder_start(&is->subdec, subtitle_thread, "subtitle_decoder", is)) < 0)
2704 avcodec_free_context(&avctx);
2706 av_dict_free(&opts);
2711 static int decode_interrupt_cb(void *ctx)
2713 VideoState *is = ctx;
2714 return is->abort_request;
2717 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2718 return stream_id < 0 ||
2719 queue->abort_request ||
2720 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2721 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2724 static int is_realtime(AVFormatContext *s)
2726 if( !strcmp(s->iformat->name, "rtp")
2727 || !strcmp(s->iformat->name, "rtsp")
2728 || !strcmp(s->iformat->name, "sdp")
2732 if(s->pb && ( !strncmp(s->url, "rtp:", 4)
2733 || !strncmp(s->url, "udp:", 4)
2740 /* this thread gets the stream from the disk or the network */
2741 static int read_thread(void *arg)
2743 VideoState *is = arg;
2744 AVFormatContext *ic = NULL;
2746 int st_index[AVMEDIA_TYPE_NB];
2747 AVPacket pkt1, *pkt = &pkt1;
2748 int64_t stream_start_time;
2749 int pkt_in_play_range = 0;
2750 AVDictionaryEntry *t;
2751 SDL_mutex *wait_mutex = SDL_CreateMutex();
2752 int scan_all_pmts_set = 0;
2756 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2757 ret = AVERROR(ENOMEM);
2761 memset(st_index, -1, sizeof(st_index));
2762 is->last_video_stream = is->video_stream = -1;
2763 is->last_audio_stream = is->audio_stream = -1;
2764 is->last_subtitle_stream = is->subtitle_stream = -1;
2767 ic = avformat_alloc_context();
2769 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2770 ret = AVERROR(ENOMEM);
2773 ic->interrupt_callback.callback = decode_interrupt_cb;
2774 ic->interrupt_callback.opaque = is;
2775 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2776 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2777 scan_all_pmts_set = 1;
2779 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2781 print_error(is->filename, err);
2785 if (scan_all_pmts_set)
2786 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2788 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2789 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2790 ret = AVERROR_OPTION_NOT_FOUND;
2796 ic->flags |= AVFMT_FLAG_GENPTS;
2798 av_format_inject_global_side_data(ic);
2800 if (find_stream_info) {
2801 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2802 int orig_nb_streams = ic->nb_streams;
2804 err = avformat_find_stream_info(ic, opts);
2806 for (i = 0; i < orig_nb_streams; i++)
2807 av_dict_free(&opts[i]);
2811 av_log(NULL, AV_LOG_WARNING,
2812 "%s: could not find codec parameters\n", is->filename);
2819 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2821 if (seek_by_bytes < 0)
2822 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2824 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2826 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2827 window_title = av_asprintf("%s - %s", t->value, input_filename);
2829 /* if seeking requested, we execute it */
2830 if (start_time != AV_NOPTS_VALUE) {
2833 timestamp = start_time;
2834 /* add the stream start time */
2835 if (ic->start_time != AV_NOPTS_VALUE)
2836 timestamp += ic->start_time;
2837 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2839 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2840 is->filename, (double)timestamp / AV_TIME_BASE);
2844 is->realtime = is_realtime(ic);
2847 av_dump_format(ic, 0, is->filename, 0);
2849 for (i = 0; i < ic->nb_streams; i++) {
2850 AVStream *st = ic->streams[i];
2851 enum AVMediaType type = st->codecpar->codec_type;
2852 st->discard = AVDISCARD_ALL;
2853 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2854 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2857 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2858 if (wanted_stream_spec[i] && st_index[i] == -1) {
2859 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));
2860 st_index[i] = INT_MAX;
2865 st_index[AVMEDIA_TYPE_VIDEO] =
2866 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2867 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2869 st_index[AVMEDIA_TYPE_AUDIO] =
2870 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2871 st_index[AVMEDIA_TYPE_AUDIO],
2872 st_index[AVMEDIA_TYPE_VIDEO],
2874 if (!video_disable && !subtitle_disable)
2875 st_index[AVMEDIA_TYPE_SUBTITLE] =
2876 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2877 st_index[AVMEDIA_TYPE_SUBTITLE],
2878 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2879 st_index[AVMEDIA_TYPE_AUDIO] :
2880 st_index[AVMEDIA_TYPE_VIDEO]),
2883 is->show_mode = show_mode;
2884 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2885 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2886 AVCodecParameters *codecpar = st->codecpar;
2887 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2888 if (codecpar->width)
2889 set_default_window_size(codecpar->width, codecpar->height, sar);
2892 /* open the streams */
2893 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2894 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2898 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2899 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2901 if (is->show_mode == SHOW_MODE_NONE)
2902 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2904 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2905 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2908 if (is->video_stream < 0 && is->audio_stream < 0) {
2909 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2915 if (infinite_buffer < 0 && is->realtime)
2916 infinite_buffer = 1;
2919 if (is->abort_request)
2921 if (is->paused != is->last_paused) {
2922 is->last_paused = is->paused;
2924 is->read_pause_return = av_read_pause(ic);
2928 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2930 (!strcmp(ic->iformat->name, "rtsp") ||
2931 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2932 /* wait 10 ms to avoid trying to get another packet */
2939 int64_t seek_target = is->seek_pos;
2940 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2941 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2942 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2943 // of the seek_pos/seek_rel variables
2945 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2947 av_log(NULL, AV_LOG_ERROR,
2948 "%s: error while seeking\n", is->ic->url);
2950 if (is->audio_stream >= 0) {
2951 packet_queue_flush(&is->audioq);
2952 packet_queue_put(&is->audioq, &flush_pkt);
2954 if (is->subtitle_stream >= 0) {
2955 packet_queue_flush(&is->subtitleq);
2956 packet_queue_put(&is->subtitleq, &flush_pkt);
2958 if (is->video_stream >= 0) {
2959 packet_queue_flush(&is->videoq);
2960 packet_queue_put(&is->videoq, &flush_pkt);
2962 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2963 set_clock(&is->extclk, NAN, 0);
2965 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2969 is->queue_attachments_req = 1;
2972 step_to_next_frame(is);
2974 if (is->queue_attachments_req) {
2975 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2976 AVPacket copy = { 0 };
2977 if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0)
2979 packet_queue_put(&is->videoq, ©);
2980 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2982 is->queue_attachments_req = 0;
2985 /* if the queue are full, no need to read more */
2986 if (infinite_buffer<1 &&
2987 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2988 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2989 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2990 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2992 SDL_LockMutex(wait_mutex);
2993 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2994 SDL_UnlockMutex(wait_mutex);
2998 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2999 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3000 if (loop != 1 && (!loop || --loop)) {
3001 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3002 } else if (autoexit) {
3007 ret = av_read_frame(ic, pkt);
3009 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3010 if (is->video_stream >= 0)
3011 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3012 if (is->audio_stream >= 0)
3013 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3014 if (is->subtitle_stream >= 0)
3015 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3018 if (ic->pb && ic->pb->error)
3020 SDL_LockMutex(wait_mutex);
3021 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3022 SDL_UnlockMutex(wait_mutex);
3027 /* check if packet is in play range specified by user, then queue, otherwise discard */
3028 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3029 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3030 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3031 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3032 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3033 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3034 <= ((double)duration / 1000000);
3035 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3036 packet_queue_put(&is->audioq, pkt);
3037 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3038 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3039 packet_queue_put(&is->videoq, pkt);
3040 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3041 packet_queue_put(&is->subtitleq, pkt);
3043 av_packet_unref(pkt);
3050 avformat_close_input(&ic);
3055 event.type = FF_QUIT_EVENT;
3056 event.user.data1 = is;
3057 SDL_PushEvent(&event);
3059 SDL_DestroyMutex(wait_mutex);
3063 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3067 is = av_mallocz(sizeof(VideoState));
3070 is->filename = av_strdup(filename);
3073 is->iformat = iformat;
3077 /* start video display */
3078 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3080 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3082 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3085 if (packet_queue_init(&is->videoq) < 0 ||
3086 packet_queue_init(&is->audioq) < 0 ||
3087 packet_queue_init(&is->subtitleq) < 0)
3090 if (!(is->continue_read_thread = SDL_CreateCond())) {
3091 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3095 init_clock(&is->vidclk, &is->videoq.serial);
3096 init_clock(&is->audclk, &is->audioq.serial);
3097 init_clock(&is->extclk, &is->extclk.serial);
3098 is->audio_clock_serial = -1;
3099 if (startup_volume < 0)
3100 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3101 if (startup_volume > 100)
3102 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3103 startup_volume = av_clip(startup_volume, 0, 100);
3104 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3105 is->audio_volume = startup_volume;
3107 is->av_sync_type = av_sync_type;
3108 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3109 if (!is->read_tid) {
3110 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3118 static void stream_cycle_channel(VideoState *is, int codec_type)
3120 AVFormatContext *ic = is->ic;
3121 int start_index, stream_index;
3124 AVProgram *p = NULL;
3125 int nb_streams = is->ic->nb_streams;
3127 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3128 start_index = is->last_video_stream;
3129 old_index = is->video_stream;
3130 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3131 start_index = is->last_audio_stream;
3132 old_index = is->audio_stream;
3134 start_index = is->last_subtitle_stream;
3135 old_index = is->subtitle_stream;
3137 stream_index = start_index;
3139 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3140 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3142 nb_streams = p->nb_stream_indexes;
3143 for (start_index = 0; start_index < nb_streams; start_index++)
3144 if (p->stream_index[start_index] == stream_index)
3146 if (start_index == nb_streams)
3148 stream_index = start_index;
3153 if (++stream_index >= nb_streams)
3155 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3158 is->last_subtitle_stream = -1;
3161 if (start_index == -1)
3165 if (stream_index == start_index)
3167 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3168 if (st->codecpar->codec_type == codec_type) {
3169 /* check that parameters are OK */
3170 switch (codec_type) {
3171 case AVMEDIA_TYPE_AUDIO:
3172 if (st->codecpar->sample_rate != 0 &&
3173 st->codecpar->channels != 0)
3176 case AVMEDIA_TYPE_VIDEO:
3177 case AVMEDIA_TYPE_SUBTITLE:
3185 if (p && stream_index != -1)
3186 stream_index = p->stream_index[stream_index];
3187 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3188 av_get_media_type_string(codec_type),
3192 stream_component_close(is, old_index);
3193 stream_component_open(is, stream_index);
3197 static void toggle_full_screen(VideoState *is)
3199 is_full_screen = !is_full_screen;
3200 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3203 static void toggle_audio_display(VideoState *is)
3205 int next = is->show_mode;
3207 next = (next + 1) % SHOW_MODE_NB;
3208 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3209 if (is->show_mode != next) {
3210 is->force_refresh = 1;
3211 is->show_mode = next;
3215 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3216 double remaining_time = 0.0;
3218 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3219 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3223 if (remaining_time > 0.0)
3224 av_usleep((int64_t)(remaining_time * 1000000.0));
3225 remaining_time = REFRESH_RATE;
3226 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3227 video_refresh(is, &remaining_time);
3232 static void seek_chapter(VideoState *is, int incr)
3234 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3237 if (!is->ic->nb_chapters)
3240 /* find the current chapter */
3241 for (i = 0; i < is->ic->nb_chapters; i++) {
3242 AVChapter *ch = is->ic->chapters[i];
3243 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3251 if (i >= is->ic->nb_chapters)
3254 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3255 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3256 AV_TIME_BASE_Q), 0, 0);
3259 /* handle an event sent by the GUI */
3260 static void event_loop(VideoState *cur_stream)
3263 double incr, pos, frac;
3267 refresh_loop_wait_event(cur_stream, &event);
3268 switch (event.type) {
3270 if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
3271 do_exit(cur_stream);
3274 // If we don't yet have a window, skip all key events, because read_thread might still be initializing...
3275 if (!cur_stream->width)
3277 switch (event.key.keysym.sym) {
3279 toggle_full_screen(cur_stream);
3280 cur_stream->force_refresh = 1;
3284 toggle_pause(cur_stream);
3287 toggle_mute(cur_stream);
3289 case SDLK_KP_MULTIPLY:
3291 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3293 case SDLK_KP_DIVIDE:
3295 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3297 case SDLK_s: // S: Step to next frame
3298 step_to_next_frame(cur_stream);
3301 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3304 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3307 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3308 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3309 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3312 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3316 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3317 if (++cur_stream->vfilter_idx >= nb_vfilters)
3318 cur_stream->vfilter_idx = 0;
3320 cur_stream->vfilter_idx = 0;
3321 toggle_audio_display(cur_stream);
3324 toggle_audio_display(cur_stream);
3328 if (cur_stream->ic->nb_chapters <= 1) {
3332 seek_chapter(cur_stream, 1);
3335 if (cur_stream->ic->nb_chapters <= 1) {
3339 seek_chapter(cur_stream, -1);
3342 incr = seek_interval ? -seek_interval : -10.0;
3345 incr = seek_interval ? seek_interval : 10.0;
3353 if (seek_by_bytes) {
3355 if (pos < 0 && cur_stream->video_stream >= 0)
3356 pos = frame_queue_last_pos(&cur_stream->pictq);
3357 if (pos < 0 && cur_stream->audio_stream >= 0)
3358 pos = frame_queue_last_pos(&cur_stream->sampq);
3360 pos = avio_tell(cur_stream->ic->pb);
3361 if (cur_stream->ic->bit_rate)
3362 incr *= cur_stream->ic->bit_rate / 8.0;
3366 stream_seek(cur_stream, pos, incr, 1);
3368 pos = get_master_clock(cur_stream);
3370 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3372 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3373 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3374 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3381 case SDL_MOUSEBUTTONDOWN:
3382 if (exit_on_mousedown) {
3383 do_exit(cur_stream);
3386 if (event.button.button == SDL_BUTTON_LEFT) {
3387 static int64_t last_mouse_left_click = 0;
3388 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3389 toggle_full_screen(cur_stream);
3390 cur_stream->force_refresh = 1;
3391 last_mouse_left_click = 0;
3393 last_mouse_left_click = av_gettime_relative();
3396 case SDL_MOUSEMOTION:
3397 if (cursor_hidden) {
3401 cursor_last_shown = av_gettime_relative();
3402 if (event.type == SDL_MOUSEBUTTONDOWN) {
3403 if (event.button.button != SDL_BUTTON_RIGHT)
3407 if (!(event.motion.state & SDL_BUTTON_RMASK))
3411 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3412 uint64_t size = avio_size(cur_stream->ic->pb);
3413 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3417 int tns, thh, tmm, tss;
3418 tns = cur_stream->ic->duration / 1000000LL;
3420 tmm = (tns % 3600) / 60;
3422 frac = x / cur_stream->width;
3425 mm = (ns % 3600) / 60;
3427 av_log(NULL, AV_LOG_INFO,
3428 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3429 hh, mm, ss, thh, tmm, tss);
3430 ts = frac * cur_stream->ic->duration;
3431 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3432 ts += cur_stream->ic->start_time;
3433 stream_seek(cur_stream, ts, 0, 0);
3436 case SDL_WINDOWEVENT:
3437 switch (event.window.event) {
3438 case SDL_WINDOWEVENT_RESIZED:
3439 screen_width = cur_stream->width = event.window.data1;
3440 screen_height = cur_stream->height = event.window.data2;
3441 if (cur_stream->vis_texture) {
3442 SDL_DestroyTexture(cur_stream->vis_texture);
3443 cur_stream->vis_texture = NULL;
3445 case SDL_WINDOWEVENT_EXPOSED:
3446 cur_stream->force_refresh = 1;
3451 do_exit(cur_stream);
3459 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3461 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3462 return opt_default(NULL, "video_size", arg);
3465 static int opt_width(void *optctx, const char *opt, const char *arg)
3467 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3471 static int opt_height(void *optctx, const char *opt, const char *arg)
3473 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3477 static int opt_format(void *optctx, const char *opt, const char *arg)
3479 file_iformat = av_find_input_format(arg);
3480 if (!file_iformat) {
3481 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3482 return AVERROR(EINVAL);
3487 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3489 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3490 return opt_default(NULL, "pixel_format", arg);
3493 static int opt_sync(void *optctx, const char *opt, const char *arg)
3495 if (!strcmp(arg, "audio"))
3496 av_sync_type = AV_SYNC_AUDIO_MASTER;
3497 else if (!strcmp(arg, "video"))
3498 av_sync_type = AV_SYNC_VIDEO_MASTER;
3499 else if (!strcmp(arg, "ext"))
3500 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3502 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3508 static int opt_seek(void *optctx, const char *opt, const char *arg)
3510 start_time = parse_time_or_die(opt, arg, 1);
3514 static int opt_duration(void *optctx, const char *opt, const char *arg)
3516 duration = parse_time_or_die(opt, arg, 1);
3520 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3522 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3523 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3524 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3525 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3529 static void opt_input_file(void *optctx, const char *filename)
3531 if (input_filename) {
3532 av_log(NULL, AV_LOG_FATAL,
3533 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3534 filename, input_filename);
3537 if (!strcmp(filename, "-"))
3539 input_filename = filename;
3542 static int opt_codec(void *optctx, const char *opt, const char *arg)
3544 const char *spec = strchr(opt, ':');
3546 av_log(NULL, AV_LOG_ERROR,
3547 "No media specifier was specified in '%s' in option '%s'\n",
3549 return AVERROR(EINVAL);
3553 case 'a' : audio_codec_name = arg; break;
3554 case 's' : subtitle_codec_name = arg; break;
3555 case 'v' : video_codec_name = arg; break;
3557 av_log(NULL, AV_LOG_ERROR,
3558 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3559 return AVERROR(EINVAL);
3566 static const OptionDef options[] = {
3567 CMDUTILS_COMMON_OPTIONS
3568 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3569 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3570 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3571 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3572 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3573 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3574 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3575 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3576 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3577 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3578 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3579 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3580 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3581 { "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
3582 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3583 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3584 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3585 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3586 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3587 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3588 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3589 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3590 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3591 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3592 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3593 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3594 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3595 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3596 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3597 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3598 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3599 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3600 { "left", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_left }, "set the x position for the left of the window", "x pos" },
3601 { "top", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_top }, "set the y position for the top of the window", "y pos" },
3603 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3604 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3606 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3607 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3608 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3609 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3610 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3611 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3612 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3613 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3614 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3615 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3616 "read and decode the streams to fill missing information with heuristics" },
3617 { "filter_threads", HAS_ARG | OPT_INT | OPT_EXPERT, { &filter_nbthreads }, "number of filter threads per graph" },
3621 static void show_usage(void)
3623 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3624 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3625 av_log(NULL, AV_LOG_INFO, "\n");
3628 void show_help_default(const char *opt, const char *arg)
3630 av_log_set_callback(log_callback_help);
3632 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3633 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3635 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3636 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3637 #if !CONFIG_AVFILTER
3638 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3640 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3642 printf("\nWhile playing:\n"
3644 "f toggle full screen\n"
3647 "9, 0 decrease and increase volume respectively\n"
3648 "/, * decrease and increase volume respectively\n"
3649 "a cycle audio channel in the current program\n"
3650 "v cycle video channel\n"
3651 "t cycle subtitle channel in the current program\n"
3653 "w cycle video filters or show modes\n"
3654 "s activate frame-step mode\n"
3655 "left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
3656 "down/up seek backward/forward 1 minute\n"
3657 "page down/page up seek backward/forward 10 minutes\n"
3658 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3659 "left double-click toggle full screen\n"
3663 /* Called from the main */
3664 int main(int argc, char **argv)
3671 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3672 parse_loglevel(argc, argv, options);
3674 /* register all codecs, demux and protocols */
3676 avdevice_register_all();
3678 avformat_network_init();
3682 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3683 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3685 show_banner(argc, argv, options);
3687 parse_options(NULL, argc, argv, options, opt_input_file);
3689 if (!input_filename) {
3691 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3692 av_log(NULL, AV_LOG_FATAL,
3693 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3697 if (display_disable) {
3700 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3702 flags &= ~SDL_INIT_AUDIO;
3704 /* Try to work around an occasional ALSA buffer underflow issue when the
3705 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3706 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3707 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3709 if (display_disable)
3710 flags &= ~SDL_INIT_VIDEO;
3711 if (SDL_Init (flags)) {
3712 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3713 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3717 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3718 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3720 av_init_packet(&flush_pkt);
3721 flush_pkt.data = (uint8_t *)&flush_pkt;
3723 if (!display_disable) {
3724 int flags = SDL_WINDOW_HIDDEN;
3726 flags |= SDL_WINDOW_BORDERLESS;
3728 flags |= SDL_WINDOW_RESIZABLE;
3729 window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
3730 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
3732 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
3734 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
3735 renderer = SDL_CreateRenderer(window, -1, 0);
3738 if (!SDL_GetRendererInfo(renderer, &renderer_info))
3739 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
3742 if (!window || !renderer || !renderer_info.num_texture_formats) {
3743 av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
3748 is = stream_open(input_filename, file_iformat);
3750 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");