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 audio_disable;
318 static int video_disable;
319 static int subtitle_disable;
320 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
321 static int seek_by_bytes = -1;
322 static float seek_interval = 10;
323 static int display_disable;
324 static int borderless;
325 static int startup_volume = 100;
326 static int show_status = 1;
327 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
328 static int64_t start_time = AV_NOPTS_VALUE;
329 static int64_t duration = AV_NOPTS_VALUE;
331 static int genpts = 0;
332 static int lowres = 0;
333 static int decoder_reorder_pts = -1;
335 static int exit_on_keydown;
336 static int exit_on_mousedown;
338 static int framedrop = -1;
339 static int infinite_buffer = -1;
340 static enum ShowMode show_mode = SHOW_MODE_NONE;
341 static const char *audio_codec_name;
342 static const char *subtitle_codec_name;
343 static const char *video_codec_name;
344 double rdftspeed = 0.02;
345 static int64_t cursor_last_shown;
346 static int cursor_hidden = 0;
348 static const char **vfilters_list = NULL;
349 static int nb_vfilters = 0;
350 static char *afilters = NULL;
352 static int autorotate = 1;
353 static int find_stream_info = 1;
355 /* current context */
356 static int is_full_screen;
357 static int64_t audio_callback_time;
359 static AVPacket flush_pkt;
361 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
363 static SDL_Window *window;
364 static SDL_Renderer *renderer;
365 static SDL_RendererInfo renderer_info = {0};
366 static SDL_AudioDeviceID audio_dev;
368 static const struct TextureFormatEntry {
369 enum AVPixelFormat format;
371 } sdl_texture_format_map[] = {
372 { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 },
373 { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 },
374 { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 },
375 { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 },
376 { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 },
377 { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 },
378 { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 },
379 { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 },
380 { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 },
381 { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 },
382 { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 },
383 { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 },
384 { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 },
385 { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 },
386 { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 },
387 { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 },
388 { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV },
389 { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 },
390 { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY },
391 { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN },
395 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
397 GROW_ARRAY(vfilters_list, nb_vfilters);
398 vfilters_list[nb_vfilters - 1] = arg;
404 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
405 enum AVSampleFormat fmt2, int64_t channel_count2)
407 /* If channel count == 1, planar and non-planar formats are the same */
408 if (channel_count1 == 1 && channel_count2 == 1)
409 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
411 return channel_count1 != channel_count2 || fmt1 != fmt2;
415 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
417 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
418 return channel_layout;
423 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
425 MyAVPacketList *pkt1;
427 if (q->abort_request)
430 pkt1 = av_malloc(sizeof(MyAVPacketList));
435 if (pkt == &flush_pkt)
437 pkt1->serial = q->serial;
442 q->last_pkt->next = pkt1;
445 q->size += pkt1->pkt.size + sizeof(*pkt1);
446 q->duration += pkt1->pkt.duration;
447 /* XXX: should duplicate packet data in DV case */
448 SDL_CondSignal(q->cond);
452 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
456 SDL_LockMutex(q->mutex);
457 ret = packet_queue_put_private(q, pkt);
458 SDL_UnlockMutex(q->mutex);
460 if (pkt != &flush_pkt && ret < 0)
461 av_packet_unref(pkt);
466 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
468 AVPacket pkt1, *pkt = &pkt1;
472 pkt->stream_index = stream_index;
473 return packet_queue_put(q, pkt);
476 /* packet queue handling */
477 static int packet_queue_init(PacketQueue *q)
479 memset(q, 0, sizeof(PacketQueue));
480 q->mutex = SDL_CreateMutex();
482 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
483 return AVERROR(ENOMEM);
485 q->cond = SDL_CreateCond();
487 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
488 return AVERROR(ENOMEM);
490 q->abort_request = 1;
494 static void packet_queue_flush(PacketQueue *q)
496 MyAVPacketList *pkt, *pkt1;
498 SDL_LockMutex(q->mutex);
499 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
501 av_packet_unref(&pkt->pkt);
509 SDL_UnlockMutex(q->mutex);
512 static void packet_queue_destroy(PacketQueue *q)
514 packet_queue_flush(q);
515 SDL_DestroyMutex(q->mutex);
516 SDL_DestroyCond(q->cond);
519 static void packet_queue_abort(PacketQueue *q)
521 SDL_LockMutex(q->mutex);
523 q->abort_request = 1;
525 SDL_CondSignal(q->cond);
527 SDL_UnlockMutex(q->mutex);
530 static void packet_queue_start(PacketQueue *q)
532 SDL_LockMutex(q->mutex);
533 q->abort_request = 0;
534 packet_queue_put_private(q, &flush_pkt);
535 SDL_UnlockMutex(q->mutex);
538 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
539 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
541 MyAVPacketList *pkt1;
544 SDL_LockMutex(q->mutex);
547 if (q->abort_request) {
554 q->first_pkt = pkt1->next;
558 q->size -= pkt1->pkt.size + sizeof(*pkt1);
559 q->duration -= pkt1->pkt.duration;
562 *serial = pkt1->serial;
570 SDL_CondWait(q->cond, q->mutex);
573 SDL_UnlockMutex(q->mutex);
577 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
578 memset(d, 0, sizeof(Decoder));
581 d->empty_queue_cond = empty_queue_cond;
582 d->start_pts = AV_NOPTS_VALUE;
586 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
587 int ret = AVERROR(EAGAIN);
592 if (d->queue->serial == d->pkt_serial) {
594 if (d->queue->abort_request)
597 switch (d->avctx->codec_type) {
598 case AVMEDIA_TYPE_VIDEO:
599 ret = avcodec_receive_frame(d->avctx, frame);
601 if (decoder_reorder_pts == -1) {
602 frame->pts = frame->best_effort_timestamp;
603 } else if (!decoder_reorder_pts) {
604 frame->pts = frame->pkt_dts;
608 case AVMEDIA_TYPE_AUDIO:
609 ret = avcodec_receive_frame(d->avctx, frame);
611 AVRational tb = (AVRational){1, frame->sample_rate};
612 if (frame->pts != AV_NOPTS_VALUE)
613 frame->pts = av_rescale_q(frame->pts, d->avctx->pkt_timebase, tb);
614 else if (d->next_pts != AV_NOPTS_VALUE)
615 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
616 if (frame->pts != AV_NOPTS_VALUE) {
617 d->next_pts = frame->pts + frame->nb_samples;
623 if (ret == AVERROR_EOF) {
624 d->finished = d->pkt_serial;
625 avcodec_flush_buffers(d->avctx);
630 } while (ret != AVERROR(EAGAIN));
634 if (d->queue->nb_packets == 0)
635 SDL_CondSignal(d->empty_queue_cond);
636 if (d->packet_pending) {
637 av_packet_move_ref(&pkt, &d->pkt);
638 d->packet_pending = 0;
640 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
643 } while (d->queue->serial != d->pkt_serial);
645 if (pkt.data == flush_pkt.data) {
646 avcodec_flush_buffers(d->avctx);
648 d->next_pts = d->start_pts;
649 d->next_pts_tb = d->start_pts_tb;
651 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
653 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
655 ret = AVERROR(EAGAIN);
657 if (got_frame && !pkt.data) {
658 d->packet_pending = 1;
659 av_packet_move_ref(&d->pkt, &pkt);
661 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
664 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
665 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
666 d->packet_pending = 1;
667 av_packet_move_ref(&d->pkt, &pkt);
670 av_packet_unref(&pkt);
675 static void decoder_destroy(Decoder *d) {
676 av_packet_unref(&d->pkt);
677 avcodec_free_context(&d->avctx);
680 static void frame_queue_unref_item(Frame *vp)
682 av_frame_unref(vp->frame);
683 avsubtitle_free(&vp->sub);
686 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
689 memset(f, 0, sizeof(FrameQueue));
690 if (!(f->mutex = SDL_CreateMutex())) {
691 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
692 return AVERROR(ENOMEM);
694 if (!(f->cond = SDL_CreateCond())) {
695 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
696 return AVERROR(ENOMEM);
699 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
700 f->keep_last = !!keep_last;
701 for (i = 0; i < f->max_size; i++)
702 if (!(f->queue[i].frame = av_frame_alloc()))
703 return AVERROR(ENOMEM);
707 static void frame_queue_destory(FrameQueue *f)
710 for (i = 0; i < f->max_size; i++) {
711 Frame *vp = &f->queue[i];
712 frame_queue_unref_item(vp);
713 av_frame_free(&vp->frame);
715 SDL_DestroyMutex(f->mutex);
716 SDL_DestroyCond(f->cond);
719 static void frame_queue_signal(FrameQueue *f)
721 SDL_LockMutex(f->mutex);
722 SDL_CondSignal(f->cond);
723 SDL_UnlockMutex(f->mutex);
726 static Frame *frame_queue_peek(FrameQueue *f)
728 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
731 static Frame *frame_queue_peek_next(FrameQueue *f)
733 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
736 static Frame *frame_queue_peek_last(FrameQueue *f)
738 return &f->queue[f->rindex];
741 static Frame *frame_queue_peek_writable(FrameQueue *f)
743 /* wait until we have space to put a new frame */
744 SDL_LockMutex(f->mutex);
745 while (f->size >= f->max_size &&
746 !f->pktq->abort_request) {
747 SDL_CondWait(f->cond, f->mutex);
749 SDL_UnlockMutex(f->mutex);
751 if (f->pktq->abort_request)
754 return &f->queue[f->windex];
757 static Frame *frame_queue_peek_readable(FrameQueue *f)
759 /* wait until we have a readable a new frame */
760 SDL_LockMutex(f->mutex);
761 while (f->size - f->rindex_shown <= 0 &&
762 !f->pktq->abort_request) {
763 SDL_CondWait(f->cond, f->mutex);
765 SDL_UnlockMutex(f->mutex);
767 if (f->pktq->abort_request)
770 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
773 static void frame_queue_push(FrameQueue *f)
775 if (++f->windex == f->max_size)
777 SDL_LockMutex(f->mutex);
779 SDL_CondSignal(f->cond);
780 SDL_UnlockMutex(f->mutex);
783 static void frame_queue_next(FrameQueue *f)
785 if (f->keep_last && !f->rindex_shown) {
789 frame_queue_unref_item(&f->queue[f->rindex]);
790 if (++f->rindex == f->max_size)
792 SDL_LockMutex(f->mutex);
794 SDL_CondSignal(f->cond);
795 SDL_UnlockMutex(f->mutex);
798 /* return the number of undisplayed frames in the queue */
799 static int frame_queue_nb_remaining(FrameQueue *f)
801 return f->size - f->rindex_shown;
804 /* return last shown position */
805 static int64_t frame_queue_last_pos(FrameQueue *f)
807 Frame *fp = &f->queue[f->rindex];
808 if (f->rindex_shown && fp->serial == f->pktq->serial)
814 static void decoder_abort(Decoder *d, FrameQueue *fq)
816 packet_queue_abort(d->queue);
817 frame_queue_signal(fq);
818 SDL_WaitThread(d->decoder_tid, NULL);
819 d->decoder_tid = NULL;
820 packet_queue_flush(d->queue);
823 static inline void fill_rectangle(int x, int y, int w, int h)
831 SDL_RenderFillRect(renderer, &rect);
834 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
838 if (!*texture || SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
842 SDL_DestroyTexture(*texture);
843 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
845 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
848 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
850 memset(pixels, 0, pitch * new_height);
851 SDL_UnlockTexture(*texture);
853 av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
858 static void calculate_display_rect(SDL_Rect *rect,
859 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
860 int pic_width, int pic_height, AVRational pic_sar)
863 int width, height, x, y;
865 if (pic_sar.num == 0)
868 aspect_ratio = av_q2d(pic_sar);
870 if (aspect_ratio <= 0.0)
872 aspect_ratio *= (float)pic_width / (float)pic_height;
874 /* XXX: we suppose the screen has a 1.0 pixel ratio */
876 width = lrint(height * aspect_ratio) & ~1;
877 if (width > scr_width) {
879 height = lrint(width / aspect_ratio) & ~1;
881 x = (scr_width - width) / 2;
882 y = (scr_height - height) / 2;
883 rect->x = scr_xleft + x;
884 rect->y = scr_ytop + y;
885 rect->w = FFMAX(width, 1);
886 rect->h = FFMAX(height, 1);
889 static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
892 *sdl_blendmode = SDL_BLENDMODE_NONE;
893 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
894 if (format == AV_PIX_FMT_RGB32 ||
895 format == AV_PIX_FMT_RGB32_1 ||
896 format == AV_PIX_FMT_BGR32 ||
897 format == AV_PIX_FMT_BGR32_1)
898 *sdl_blendmode = SDL_BLENDMODE_BLEND;
899 for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
900 if (format == sdl_texture_format_map[i].format) {
901 *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
907 static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
910 SDL_BlendMode sdl_blendmode;
911 get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
912 if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
914 switch (sdl_pix_fmt) {
915 case SDL_PIXELFORMAT_UNKNOWN:
916 /* This should only happen if we are not using avfilter... */
917 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
918 frame->width, frame->height, frame->format, frame->width, frame->height,
919 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
920 if (*img_convert_ctx != NULL) {
923 if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
924 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
925 0, frame->height, pixels, pitch);
926 SDL_UnlockTexture(*tex);
929 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
933 case SDL_PIXELFORMAT_IYUV:
934 if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
935 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
936 frame->data[1], frame->linesize[1],
937 frame->data[2], frame->linesize[2]);
938 } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) {
939 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0],
940 frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
941 frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
943 av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
948 if (frame->linesize[0] < 0) {
949 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
951 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
958 static void set_sdl_yuv_conversion_mode(AVFrame *frame)
960 #if SDL_VERSION_ATLEAST(2,0,8)
961 SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
962 if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
963 if (frame->color_range == AVCOL_RANGE_JPEG)
964 mode = SDL_YUV_CONVERSION_JPEG;
965 else if (frame->colorspace == AVCOL_SPC_BT709)
966 mode = SDL_YUV_CONVERSION_BT709;
967 else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
968 mode = SDL_YUV_CONVERSION_BT601;
970 SDL_SetYUVConversionMode(mode);
974 static void video_image_display(VideoState *is)
980 vp = frame_queue_peek_last(&is->pictq);
981 if (is->subtitle_st) {
982 if (frame_queue_nb_remaining(&is->subpq) > 0) {
983 sp = frame_queue_peek(&is->subpq);
985 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
990 if (!sp->width || !sp->height) {
991 sp->width = vp->width;
992 sp->height = vp->height;
994 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
997 for (i = 0; i < sp->sub.num_rects; i++) {
998 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1000 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
1001 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
1002 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
1003 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
1005 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
1006 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
1007 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
1008 0, NULL, NULL, NULL);
1009 if (!is->sub_convert_ctx) {
1010 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1013 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
1014 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
1015 0, sub_rect->h, pixels, pitch);
1016 SDL_UnlockTexture(is->sub_texture);
1026 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1028 if (!vp->uploaded) {
1029 if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
1032 vp->flip_v = vp->frame->linesize[0] < 0;
1035 set_sdl_yuv_conversion_mode(vp->frame);
1036 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
1037 set_sdl_yuv_conversion_mode(NULL);
1039 #if USE_ONEPASS_SUBTITLE_RENDER
1040 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
1043 double xratio = (double)rect.w / (double)sp->width;
1044 double yratio = (double)rect.h / (double)sp->height;
1045 for (i = 0; i < sp->sub.num_rects; i++) {
1046 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
1047 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
1048 .y = rect.y + sub_rect->y * yratio,
1049 .w = sub_rect->w * xratio,
1050 .h = sub_rect->h * yratio};
1051 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
1057 static inline int compute_mod(int a, int b)
1059 return a < 0 ? a%b + b : a%b;
1062 static void video_audio_display(VideoState *s)
1064 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1065 int ch, channels, h, h2;
1067 int rdft_bits, nb_freq;
1069 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1071 nb_freq = 1 << (rdft_bits - 1);
1073 /* compute display index : center on currently output samples */
1074 channels = s->audio_tgt.channels;
1075 nb_display_channels = channels;
1077 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1079 delay = s->audio_write_buf_size;
1082 /* to be more precise, we take into account the time spent since
1083 the last buffer computation */
1084 if (audio_callback_time) {
1085 time_diff = av_gettime_relative() - audio_callback_time;
1086 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1089 delay += 2 * data_used;
1090 if (delay < data_used)
1093 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1094 if (s->show_mode == SHOW_MODE_WAVES) {
1096 for (i = 0; i < 1000; i += channels) {
1097 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1098 int a = s->sample_array[idx];
1099 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1100 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1101 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1103 if (h < score && (b ^ c) < 0) {
1110 s->last_i_start = i_start;
1112 i_start = s->last_i_start;
1115 if (s->show_mode == SHOW_MODE_WAVES) {
1116 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1118 /* total height for one channel */
1119 h = s->height / nb_display_channels;
1120 /* graph height / 2 */
1122 for (ch = 0; ch < nb_display_channels; ch++) {
1124 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1125 for (x = 0; x < s->width; x++) {
1126 y = (s->sample_array[i] * h2) >> 15;
1133 fill_rectangle(s->xleft + x, ys, 1, y);
1135 if (i >= SAMPLE_ARRAY_SIZE)
1136 i -= SAMPLE_ARRAY_SIZE;
1140 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1142 for (ch = 1; ch < nb_display_channels; ch++) {
1143 y = s->ytop + ch * h;
1144 fill_rectangle(s->xleft, y, s->width, 1);
1147 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1150 nb_display_channels= FFMIN(nb_display_channels, 2);
1151 if (rdft_bits != s->rdft_bits) {
1152 av_rdft_end(s->rdft);
1153 av_free(s->rdft_data);
1154 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1155 s->rdft_bits = rdft_bits;
1156 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1158 if (!s->rdft || !s->rdft_data){
1159 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1160 s->show_mode = SHOW_MODE_WAVES;
1163 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1166 for (ch = 0; ch < nb_display_channels; ch++) {
1167 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1169 for (x = 0; x < 2 * nb_freq; x++) {
1170 double w = (x-nb_freq) * (1.0 / nb_freq);
1171 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1173 if (i >= SAMPLE_ARRAY_SIZE)
1174 i -= SAMPLE_ARRAY_SIZE;
1176 av_rdft_calc(s->rdft, data[ch]);
1178 /* Least efficient way to do this, we should of course
1179 * directly access it but it is more than fast enough. */
1180 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1182 pixels += pitch * s->height;
1183 for (y = 0; y < s->height; y++) {
1184 double w = 1 / sqrt(nb_freq);
1185 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
1186 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1191 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1193 SDL_UnlockTexture(s->vis_texture);
1195 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1199 if (s->xpos >= s->width)
1204 static void stream_component_close(VideoState *is, int stream_index)
1206 AVFormatContext *ic = is->ic;
1207 AVCodecParameters *codecpar;
1209 if (stream_index < 0 || stream_index >= ic->nb_streams)
1211 codecpar = ic->streams[stream_index]->codecpar;
1213 switch (codecpar->codec_type) {
1214 case AVMEDIA_TYPE_AUDIO:
1215 decoder_abort(&is->auddec, &is->sampq);
1216 SDL_CloseAudioDevice(audio_dev);
1217 decoder_destroy(&is->auddec);
1218 swr_free(&is->swr_ctx);
1219 av_freep(&is->audio_buf1);
1220 is->audio_buf1_size = 0;
1221 is->audio_buf = NULL;
1224 av_rdft_end(is->rdft);
1225 av_freep(&is->rdft_data);
1230 case AVMEDIA_TYPE_VIDEO:
1231 decoder_abort(&is->viddec, &is->pictq);
1232 decoder_destroy(&is->viddec);
1234 case AVMEDIA_TYPE_SUBTITLE:
1235 decoder_abort(&is->subdec, &is->subpq);
1236 decoder_destroy(&is->subdec);
1242 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1243 switch (codecpar->codec_type) {
1244 case AVMEDIA_TYPE_AUDIO:
1245 is->audio_st = NULL;
1246 is->audio_stream = -1;
1248 case AVMEDIA_TYPE_VIDEO:
1249 is->video_st = NULL;
1250 is->video_stream = -1;
1252 case AVMEDIA_TYPE_SUBTITLE:
1253 is->subtitle_st = NULL;
1254 is->subtitle_stream = -1;
1261 static void stream_close(VideoState *is)
1263 /* XXX: use a special url_shutdown call to abort parse cleanly */
1264 is->abort_request = 1;
1265 SDL_WaitThread(is->read_tid, NULL);
1267 /* close each stream */
1268 if (is->audio_stream >= 0)
1269 stream_component_close(is, is->audio_stream);
1270 if (is->video_stream >= 0)
1271 stream_component_close(is, is->video_stream);
1272 if (is->subtitle_stream >= 0)
1273 stream_component_close(is, is->subtitle_stream);
1275 avformat_close_input(&is->ic);
1277 packet_queue_destroy(&is->videoq);
1278 packet_queue_destroy(&is->audioq);
1279 packet_queue_destroy(&is->subtitleq);
1281 /* free all pictures */
1282 frame_queue_destory(&is->pictq);
1283 frame_queue_destory(&is->sampq);
1284 frame_queue_destory(&is->subpq);
1285 SDL_DestroyCond(is->continue_read_thread);
1286 sws_freeContext(is->img_convert_ctx);
1287 sws_freeContext(is->sub_convert_ctx);
1288 av_free(is->filename);
1289 if (is->vis_texture)
1290 SDL_DestroyTexture(is->vis_texture);
1291 if (is->vid_texture)
1292 SDL_DestroyTexture(is->vid_texture);
1293 if (is->sub_texture)
1294 SDL_DestroyTexture(is->sub_texture);
1298 static void do_exit(VideoState *is)
1304 SDL_DestroyRenderer(renderer);
1306 SDL_DestroyWindow(window);
1309 av_freep(&vfilters_list);
1311 avformat_network_deinit();
1315 av_log(NULL, AV_LOG_QUIET, "%s", "");
1319 static void sigterm_handler(int sig)
1324 static void set_default_window_size(int width, int height, AVRational sar)
1327 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1328 default_width = rect.w;
1329 default_height = rect.h;
1332 static int video_open(VideoState *is)
1345 window_title = input_filename;
1346 SDL_SetWindowTitle(window, window_title);
1348 SDL_SetWindowSize(window, w, h);
1349 SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
1351 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1352 SDL_ShowWindow(window);
1360 /* display the current picture, if any */
1361 static void video_display(VideoState *is)
1366 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1367 SDL_RenderClear(renderer);
1368 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1369 video_audio_display(is);
1370 else if (is->video_st)
1371 video_image_display(is);
1372 SDL_RenderPresent(renderer);
1375 static double get_clock(Clock *c)
1377 if (*c->queue_serial != c->serial)
1382 double time = av_gettime_relative() / 1000000.0;
1383 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1387 static void set_clock_at(Clock *c, double pts, int serial, double time)
1390 c->last_updated = time;
1391 c->pts_drift = c->pts - time;
1395 static void set_clock(Clock *c, double pts, int serial)
1397 double time = av_gettime_relative() / 1000000.0;
1398 set_clock_at(c, pts, serial, time);
1401 static void set_clock_speed(Clock *c, double speed)
1403 set_clock(c, get_clock(c), c->serial);
1407 static void init_clock(Clock *c, int *queue_serial)
1411 c->queue_serial = queue_serial;
1412 set_clock(c, NAN, -1);
1415 static void sync_clock_to_slave(Clock *c, Clock *slave)
1417 double clock = get_clock(c);
1418 double slave_clock = get_clock(slave);
1419 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1420 set_clock(c, slave_clock, slave->serial);
1423 static int get_master_sync_type(VideoState *is) {
1424 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1426 return AV_SYNC_VIDEO_MASTER;
1428 return AV_SYNC_AUDIO_MASTER;
1429 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1431 return AV_SYNC_AUDIO_MASTER;
1433 return AV_SYNC_EXTERNAL_CLOCK;
1435 return AV_SYNC_EXTERNAL_CLOCK;
1439 /* get the current master clock value */
1440 static double get_master_clock(VideoState *is)
1444 switch (get_master_sync_type(is)) {
1445 case AV_SYNC_VIDEO_MASTER:
1446 val = get_clock(&is->vidclk);
1448 case AV_SYNC_AUDIO_MASTER:
1449 val = get_clock(&is->audclk);
1452 val = get_clock(&is->extclk);
1458 static void check_external_clock_speed(VideoState *is) {
1459 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1460 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1461 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1462 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1463 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1464 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1466 double speed = is->extclk.speed;
1468 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1472 /* seek in the stream */
1473 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1475 if (!is->seek_req) {
1478 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1480 is->seek_flags |= AVSEEK_FLAG_BYTE;
1482 SDL_CondSignal(is->continue_read_thread);
1486 /* pause or resume the video */
1487 static void stream_toggle_pause(VideoState *is)
1490 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1491 if (is->read_pause_return != AVERROR(ENOSYS)) {
1492 is->vidclk.paused = 0;
1494 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1496 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1497 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1500 static void toggle_pause(VideoState *is)
1502 stream_toggle_pause(is);
1506 static void toggle_mute(VideoState *is)
1508 is->muted = !is->muted;
1511 static void update_volume(VideoState *is, int sign, double step)
1513 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1514 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1515 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1518 static void step_to_next_frame(VideoState *is)
1520 /* if the stream is paused unpause it, then step */
1522 stream_toggle_pause(is);
1526 static double compute_target_delay(double delay, VideoState *is)
1528 double sync_threshold, diff = 0;
1530 /* update delay to follow master synchronisation source */
1531 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1532 /* if video is slave, we try to correct big delays by
1533 duplicating or deleting a frame */
1534 diff = get_clock(&is->vidclk) - get_master_clock(is);
1536 /* skip or repeat frame. We take into account the
1537 delay to compute the threshold. I still don't know
1538 if it is the best guess */
1539 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1540 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1541 if (diff <= -sync_threshold)
1542 delay = FFMAX(0, delay + diff);
1543 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1544 delay = delay + diff;
1545 else if (diff >= sync_threshold)
1550 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1556 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1557 if (vp->serial == nextvp->serial) {
1558 double duration = nextvp->pts - vp->pts;
1559 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1560 return vp->duration;
1568 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1569 /* update current video pts */
1570 set_clock(&is->vidclk, pts, serial);
1571 sync_clock_to_slave(&is->extclk, &is->vidclk);
1574 /* called to display each frame */
1575 static void video_refresh(void *opaque, double *remaining_time)
1577 VideoState *is = opaque;
1582 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1583 check_external_clock_speed(is);
1585 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1586 time = av_gettime_relative() / 1000000.0;
1587 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1589 is->last_vis_time = time;
1591 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1596 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1597 // nothing to do, no picture to display in the queue
1599 double last_duration, duration, delay;
1602 /* dequeue the picture */
1603 lastvp = frame_queue_peek_last(&is->pictq);
1604 vp = frame_queue_peek(&is->pictq);
1606 if (vp->serial != is->videoq.serial) {
1607 frame_queue_next(&is->pictq);
1611 if (lastvp->serial != vp->serial)
1612 is->frame_timer = av_gettime_relative() / 1000000.0;
1617 /* compute nominal last_duration */
1618 last_duration = vp_duration(is, lastvp, vp);
1619 delay = compute_target_delay(last_duration, is);
1621 time= av_gettime_relative()/1000000.0;
1622 if (time < is->frame_timer + delay) {
1623 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1627 is->frame_timer += delay;
1628 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1629 is->frame_timer = time;
1631 SDL_LockMutex(is->pictq.mutex);
1632 if (!isnan(vp->pts))
1633 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1634 SDL_UnlockMutex(is->pictq.mutex);
1636 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1637 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1638 duration = vp_duration(is, vp, nextvp);
1639 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1640 is->frame_drops_late++;
1641 frame_queue_next(&is->pictq);
1646 if (is->subtitle_st) {
1647 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1648 sp = frame_queue_peek(&is->subpq);
1650 if (frame_queue_nb_remaining(&is->subpq) > 1)
1651 sp2 = frame_queue_peek_next(&is->subpq);
1655 if (sp->serial != is->subtitleq.serial
1656 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1657 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1661 for (i = 0; i < sp->sub.num_rects; i++) {
1662 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1666 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1667 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1668 memset(pixels, 0, sub_rect->w << 2);
1669 SDL_UnlockTexture(is->sub_texture);
1673 frame_queue_next(&is->subpq);
1680 frame_queue_next(&is->pictq);
1681 is->force_refresh = 1;
1683 if (is->step && !is->paused)
1684 stream_toggle_pause(is);
1687 /* display picture */
1688 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1691 is->force_refresh = 0;
1693 static int64_t last_time;
1695 int aqsize, vqsize, sqsize;
1698 cur_time = av_gettime_relative();
1699 if (!last_time || (cur_time - last_time) >= 30000) {
1704 aqsize = is->audioq.size;
1706 vqsize = is->videoq.size;
1707 if (is->subtitle_st)
1708 sqsize = is->subtitleq.size;
1710 if (is->audio_st && is->video_st)
1711 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1712 else if (is->video_st)
1713 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1714 else if (is->audio_st)
1715 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1716 av_log(NULL, AV_LOG_INFO,
1717 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1718 get_master_clock(is),
1719 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1721 is->frame_drops_early + is->frame_drops_late,
1725 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1726 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1728 last_time = cur_time;
1733 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1737 #if defined(DEBUG_SYNC)
1738 printf("frame_type=%c pts=%0.3f\n",
1739 av_get_picture_type_char(src_frame->pict_type), pts);
1742 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1745 vp->sar = src_frame->sample_aspect_ratio;
1748 vp->width = src_frame->width;
1749 vp->height = src_frame->height;
1750 vp->format = src_frame->format;
1753 vp->duration = duration;
1755 vp->serial = serial;
1757 set_default_window_size(vp->width, vp->height, vp->sar);
1759 av_frame_move_ref(vp->frame, src_frame);
1760 frame_queue_push(&is->pictq);
1764 static int get_video_frame(VideoState *is, AVFrame *frame)
1768 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1774 if (frame->pts != AV_NOPTS_VALUE)
1775 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1777 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1779 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1780 if (frame->pts != AV_NOPTS_VALUE) {
1781 double diff = dpts - get_master_clock(is);
1782 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1783 diff - is->frame_last_filter_delay < 0 &&
1784 is->viddec.pkt_serial == is->vidclk.serial &&
1785 is->videoq.nb_packets) {
1786 is->frame_drops_early++;
1787 av_frame_unref(frame);
1798 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1799 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1802 int nb_filters = graph->nb_filters;
1803 AVFilterInOut *outputs = NULL, *inputs = NULL;
1806 outputs = avfilter_inout_alloc();
1807 inputs = avfilter_inout_alloc();
1808 if (!outputs || !inputs) {
1809 ret = AVERROR(ENOMEM);
1813 outputs->name = av_strdup("in");
1814 outputs->filter_ctx = source_ctx;
1815 outputs->pad_idx = 0;
1816 outputs->next = NULL;
1818 inputs->name = av_strdup("out");
1819 inputs->filter_ctx = sink_ctx;
1820 inputs->pad_idx = 0;
1821 inputs->next = NULL;
1823 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1826 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1830 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1831 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1832 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1834 ret = avfilter_graph_config(graph, NULL);
1836 avfilter_inout_free(&outputs);
1837 avfilter_inout_free(&inputs);
1841 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1843 enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
1844 char sws_flags_str[512] = "";
1845 char buffersrc_args[256];
1847 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1848 AVCodecParameters *codecpar = is->video_st->codecpar;
1849 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1850 AVDictionaryEntry *e = NULL;
1851 int nb_pix_fmts = 0;
1854 for (i = 0; i < renderer_info.num_texture_formats; i++) {
1855 for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; j++) {
1856 if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
1857 pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
1862 pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
1864 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1865 if (!strcmp(e->key, "sws_flags")) {
1866 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1868 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1870 if (strlen(sws_flags_str))
1871 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1873 graph->scale_sws_opts = av_strdup(sws_flags_str);
1875 snprintf(buffersrc_args, sizeof(buffersrc_args),
1876 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1877 frame->width, frame->height, frame->format,
1878 is->video_st->time_base.num, is->video_st->time_base.den,
1879 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1880 if (fr.num && fr.den)
1881 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1883 if ((ret = avfilter_graph_create_filter(&filt_src,
1884 avfilter_get_by_name("buffer"),
1885 "ffplay_buffer", buffersrc_args, NULL,
1889 ret = avfilter_graph_create_filter(&filt_out,
1890 avfilter_get_by_name("buffersink"),
1891 "ffplay_buffersink", NULL, NULL, graph);
1895 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1898 last_filter = filt_out;
1900 /* Note: this macro adds a filter before the lastly added filter, so the
1901 * processing order of the filters is in reverse */
1902 #define INSERT_FILT(name, arg) do { \
1903 AVFilterContext *filt_ctx; \
1905 ret = avfilter_graph_create_filter(&filt_ctx, \
1906 avfilter_get_by_name(name), \
1907 "ffplay_" name, arg, NULL, graph); \
1911 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1915 last_filter = filt_ctx; \
1919 double theta = get_rotation(is->video_st);
1921 if (fabs(theta - 90) < 1.0) {
1922 INSERT_FILT("transpose", "clock");
1923 } else if (fabs(theta - 180) < 1.0) {
1924 INSERT_FILT("hflip", NULL);
1925 INSERT_FILT("vflip", NULL);
1926 } else if (fabs(theta - 270) < 1.0) {
1927 INSERT_FILT("transpose", "cclock");
1928 } else if (fabs(theta) > 1.0) {
1929 char rotate_buf[64];
1930 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1931 INSERT_FILT("rotate", rotate_buf);
1935 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1938 is->in_video_filter = filt_src;
1939 is->out_video_filter = filt_out;
1945 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1947 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1948 int sample_rates[2] = { 0, -1 };
1949 int64_t channel_layouts[2] = { 0, -1 };
1950 int channels[2] = { 0, -1 };
1951 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1952 char aresample_swr_opts[512] = "";
1953 AVDictionaryEntry *e = NULL;
1954 char asrc_args[256];
1957 avfilter_graph_free(&is->agraph);
1958 if (!(is->agraph = avfilter_graph_alloc()))
1959 return AVERROR(ENOMEM);
1961 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1962 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1963 if (strlen(aresample_swr_opts))
1964 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1965 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1967 ret = snprintf(asrc_args, sizeof(asrc_args),
1968 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1969 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1970 is->audio_filter_src.channels,
1971 1, is->audio_filter_src.freq);
1972 if (is->audio_filter_src.channel_layout)
1973 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1974 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1976 ret = avfilter_graph_create_filter(&filt_asrc,
1977 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1978 asrc_args, NULL, is->agraph);
1983 ret = avfilter_graph_create_filter(&filt_asink,
1984 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1985 NULL, NULL, is->agraph);
1989 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1991 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1994 if (force_output_format) {
1995 channel_layouts[0] = is->audio_tgt.channel_layout;
1996 channels [0] = is->audio_tgt.channels;
1997 sample_rates [0] = is->audio_tgt.freq;
1998 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2000 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2002 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2004 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2009 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2012 is->in_audio_filter = filt_asrc;
2013 is->out_audio_filter = filt_asink;
2017 avfilter_graph_free(&is->agraph);
2020 #endif /* CONFIG_AVFILTER */
2022 static int audio_thread(void *arg)
2024 VideoState *is = arg;
2025 AVFrame *frame = av_frame_alloc();
2028 int last_serial = -1;
2029 int64_t dec_channel_layout;
2037 return AVERROR(ENOMEM);
2040 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2044 tb = (AVRational){1, frame->sample_rate};
2047 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
2050 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2051 frame->format, frame->channels) ||
2052 is->audio_filter_src.channel_layout != dec_channel_layout ||
2053 is->audio_filter_src.freq != frame->sample_rate ||
2054 is->auddec.pkt_serial != last_serial;
2057 char buf1[1024], buf2[1024];
2058 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2059 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2060 av_log(NULL, AV_LOG_DEBUG,
2061 "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
2062 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2063 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2065 is->audio_filter_src.fmt = frame->format;
2066 is->audio_filter_src.channels = frame->channels;
2067 is->audio_filter_src.channel_layout = dec_channel_layout;
2068 is->audio_filter_src.freq = frame->sample_rate;
2069 last_serial = is->auddec.pkt_serial;
2071 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2075 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2078 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2079 tb = av_buffersink_get_time_base(is->out_audio_filter);
2081 if (!(af = frame_queue_peek_writable(&is->sampq)))
2084 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2085 af->pos = frame->pkt_pos;
2086 af->serial = is->auddec.pkt_serial;
2087 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2089 av_frame_move_ref(af->frame, frame);
2090 frame_queue_push(&is->sampq);
2093 if (is->audioq.serial != is->auddec.pkt_serial)
2096 if (ret == AVERROR_EOF)
2097 is->auddec.finished = is->auddec.pkt_serial;
2100 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2103 avfilter_graph_free(&is->agraph);
2105 av_frame_free(&frame);
2109 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2111 packet_queue_start(d->queue);
2112 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2113 if (!d->decoder_tid) {
2114 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2115 return AVERROR(ENOMEM);
2120 static int video_thread(void *arg)
2122 VideoState *is = arg;
2123 AVFrame *frame = av_frame_alloc();
2127 AVRational tb = is->video_st->time_base;
2128 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2131 AVFilterGraph *graph = avfilter_graph_alloc();
2132 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2135 enum AVPixelFormat last_format = -2;
2136 int last_serial = -1;
2137 int last_vfilter_idx = 0;
2139 av_frame_free(&frame);
2140 return AVERROR(ENOMEM);
2147 avfilter_graph_free(&graph);
2149 return AVERROR(ENOMEM);
2153 ret = get_video_frame(is, frame);
2160 if ( last_w != frame->width
2161 || last_h != frame->height
2162 || last_format != frame->format
2163 || last_serial != is->viddec.pkt_serial
2164 || last_vfilter_idx != is->vfilter_idx) {
2165 av_log(NULL, AV_LOG_DEBUG,
2166 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2168 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2169 frame->width, frame->height,
2170 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2171 avfilter_graph_free(&graph);
2172 graph = avfilter_graph_alloc();
2173 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2175 event.type = FF_QUIT_EVENT;
2176 event.user.data1 = is;
2177 SDL_PushEvent(&event);
2180 filt_in = is->in_video_filter;
2181 filt_out = is->out_video_filter;
2182 last_w = frame->width;
2183 last_h = frame->height;
2184 last_format = frame->format;
2185 last_serial = is->viddec.pkt_serial;
2186 last_vfilter_idx = is->vfilter_idx;
2187 frame_rate = av_buffersink_get_frame_rate(filt_out);
2190 ret = av_buffersrc_add_frame(filt_in, frame);
2195 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2197 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2199 if (ret == AVERROR_EOF)
2200 is->viddec.finished = is->viddec.pkt_serial;
2205 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2206 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2207 is->frame_last_filter_delay = 0;
2208 tb = av_buffersink_get_time_base(filt_out);
2210 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2211 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2212 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2213 av_frame_unref(frame);
2215 if (is->videoq.serial != is->viddec.pkt_serial)
2225 avfilter_graph_free(&graph);
2227 av_frame_free(&frame);
2231 static int subtitle_thread(void *arg)
2233 VideoState *is = arg;
2239 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2242 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2247 if (got_subtitle && sp->sub.format == 0) {
2248 if (sp->sub.pts != AV_NOPTS_VALUE)
2249 pts = sp->sub.pts / (double)AV_TIME_BASE;
2251 sp->serial = is->subdec.pkt_serial;
2252 sp->width = is->subdec.avctx->width;
2253 sp->height = is->subdec.avctx->height;
2256 /* now we can update the picture count */
2257 frame_queue_push(&is->subpq);
2258 } else if (got_subtitle) {
2259 avsubtitle_free(&sp->sub);
2265 /* copy samples for viewing in editor window */
2266 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2270 size = samples_size / sizeof(short);
2272 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2275 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2277 is->sample_array_index += len;
2278 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2279 is->sample_array_index = 0;
2284 /* return the wanted number of samples to get better sync if sync_type is video
2285 * or external master clock */
2286 static int synchronize_audio(VideoState *is, int nb_samples)
2288 int wanted_nb_samples = nb_samples;
2290 /* if not master, then we try to remove or add samples to correct the clock */
2291 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2292 double diff, avg_diff;
2293 int min_nb_samples, max_nb_samples;
2295 diff = get_clock(&is->audclk) - get_master_clock(is);
2297 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2298 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2299 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2300 /* not enough measures to have a correct estimate */
2301 is->audio_diff_avg_count++;
2303 /* estimate the A-V difference */
2304 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2306 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2307 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2308 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2309 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2310 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2312 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2313 diff, avg_diff, wanted_nb_samples - nb_samples,
2314 is->audio_clock, is->audio_diff_threshold);
2317 /* too big difference : may be initial PTS errors, so
2319 is->audio_diff_avg_count = 0;
2320 is->audio_diff_cum = 0;
2324 return wanted_nb_samples;
2328 * Decode one audio frame and return its uncompressed size.
2330 * The processed audio frame is decoded, converted if required, and
2331 * stored in is->audio_buf, with size in bytes given by the return
2334 static int audio_decode_frame(VideoState *is)
2336 int data_size, resampled_data_size;
2337 int64_t dec_channel_layout;
2338 av_unused double audio_clock0;
2339 int wanted_nb_samples;
2347 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2348 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2353 if (!(af = frame_queue_peek_readable(&is->sampq)))
2355 frame_queue_next(&is->sampq);
2356 } while (af->serial != is->audioq.serial);
2358 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2359 af->frame->nb_samples,
2360 af->frame->format, 1);
2362 dec_channel_layout =
2363 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2364 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2365 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2367 if (af->frame->format != is->audio_src.fmt ||
2368 dec_channel_layout != is->audio_src.channel_layout ||
2369 af->frame->sample_rate != is->audio_src.freq ||
2370 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2371 swr_free(&is->swr_ctx);
2372 is->swr_ctx = swr_alloc_set_opts(NULL,
2373 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2374 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2376 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2377 av_log(NULL, AV_LOG_ERROR,
2378 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2379 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2380 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2381 swr_free(&is->swr_ctx);
2384 is->audio_src.channel_layout = dec_channel_layout;
2385 is->audio_src.channels = af->frame->channels;
2386 is->audio_src.freq = af->frame->sample_rate;
2387 is->audio_src.fmt = af->frame->format;
2391 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2392 uint8_t **out = &is->audio_buf1;
2393 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2394 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2397 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2400 if (wanted_nb_samples != af->frame->nb_samples) {
2401 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2402 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2403 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2407 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2408 if (!is->audio_buf1)
2409 return AVERROR(ENOMEM);
2410 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2412 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2415 if (len2 == out_count) {
2416 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2417 if (swr_init(is->swr_ctx) < 0)
2418 swr_free(&is->swr_ctx);
2420 is->audio_buf = is->audio_buf1;
2421 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2423 is->audio_buf = af->frame->data[0];
2424 resampled_data_size = data_size;
2427 audio_clock0 = is->audio_clock;
2428 /* update the audio clock with the pts */
2429 if (!isnan(af->pts))
2430 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2432 is->audio_clock = NAN;
2433 is->audio_clock_serial = af->serial;
2436 static double last_clock;
2437 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2438 is->audio_clock - last_clock,
2439 is->audio_clock, audio_clock0);
2440 last_clock = is->audio_clock;
2443 return resampled_data_size;
2446 /* prepare a new audio buffer */
2447 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2449 VideoState *is = opaque;
2450 int audio_size, len1;
2452 audio_callback_time = av_gettime_relative();
2455 if (is->audio_buf_index >= is->audio_buf_size) {
2456 audio_size = audio_decode_frame(is);
2457 if (audio_size < 0) {
2458 /* if error, just output silence */
2459 is->audio_buf = NULL;
2460 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2462 if (is->show_mode != SHOW_MODE_VIDEO)
2463 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2464 is->audio_buf_size = audio_size;
2466 is->audio_buf_index = 0;
2468 len1 = is->audio_buf_size - is->audio_buf_index;
2471 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2472 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2474 memset(stream, 0, len1);
2475 if (!is->muted && is->audio_buf)
2476 SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
2480 is->audio_buf_index += len1;
2482 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2483 /* Let's assume the audio driver that is used by SDL has two periods. */
2484 if (!isnan(is->audio_clock)) {
2485 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);
2486 sync_clock_to_slave(&is->extclk, &is->audclk);
2490 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2492 SDL_AudioSpec wanted_spec, spec;
2494 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2495 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2496 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2498 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2500 wanted_nb_channels = atoi(env);
2501 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2503 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2504 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2505 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2507 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2508 wanted_spec.channels = wanted_nb_channels;
2509 wanted_spec.freq = wanted_sample_rate;
2510 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2511 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2514 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2515 next_sample_rate_idx--;
2516 wanted_spec.format = AUDIO_S16SYS;
2517 wanted_spec.silence = 0;
2518 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2519 wanted_spec.callback = sdl_audio_callback;
2520 wanted_spec.userdata = opaque;
2521 while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
2522 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2523 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2524 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2525 if (!wanted_spec.channels) {
2526 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2527 wanted_spec.channels = wanted_nb_channels;
2528 if (!wanted_spec.freq) {
2529 av_log(NULL, AV_LOG_ERROR,
2530 "No more combinations to try, audio open failed\n");
2534 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2536 if (spec.format != AUDIO_S16SYS) {
2537 av_log(NULL, AV_LOG_ERROR,
2538 "SDL advised audio format %d is not supported!\n", spec.format);
2541 if (spec.channels != wanted_spec.channels) {
2542 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2543 if (!wanted_channel_layout) {
2544 av_log(NULL, AV_LOG_ERROR,
2545 "SDL advised channel count %d is not supported!\n", spec.channels);
2550 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2551 audio_hw_params->freq = spec.freq;
2552 audio_hw_params->channel_layout = wanted_channel_layout;
2553 audio_hw_params->channels = spec.channels;
2554 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2555 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);
2556 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2557 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2563 /* open a given stream. Return 0 if OK */
2564 static int stream_component_open(VideoState *is, int stream_index)
2566 AVFormatContext *ic = is->ic;
2567 AVCodecContext *avctx;
2569 const char *forced_codec_name = NULL;
2570 AVDictionary *opts = NULL;
2571 AVDictionaryEntry *t = NULL;
2572 int sample_rate, nb_channels;
2573 int64_t channel_layout;
2575 int stream_lowres = lowres;
2577 if (stream_index < 0 || stream_index >= ic->nb_streams)
2580 avctx = avcodec_alloc_context3(NULL);
2582 return AVERROR(ENOMEM);
2584 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2587 avctx->pkt_timebase = ic->streams[stream_index]->time_base;
2589 codec = avcodec_find_decoder(avctx->codec_id);
2591 switch(avctx->codec_type){
2592 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2593 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2594 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2596 if (forced_codec_name)
2597 codec = avcodec_find_decoder_by_name(forced_codec_name);
2599 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2600 "No codec could be found with name '%s'\n", forced_codec_name);
2601 else av_log(NULL, AV_LOG_WARNING,
2602 "No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
2603 ret = AVERROR(EINVAL);
2607 avctx->codec_id = codec->id;
2608 if (stream_lowres > codec->max_lowres) {
2609 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2611 stream_lowres = codec->max_lowres;
2613 avctx->lowres = stream_lowres;
2616 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2618 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2619 if (!av_dict_get(opts, "threads", NULL, 0))
2620 av_dict_set(&opts, "threads", "auto", 0);
2622 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2623 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2624 av_dict_set(&opts, "refcounted_frames", "1", 0);
2625 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2628 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2629 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2630 ret = AVERROR_OPTION_NOT_FOUND;
2635 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2636 switch (avctx->codec_type) {
2637 case AVMEDIA_TYPE_AUDIO:
2640 AVFilterContext *sink;
2642 is->audio_filter_src.freq = avctx->sample_rate;
2643 is->audio_filter_src.channels = avctx->channels;
2644 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2645 is->audio_filter_src.fmt = avctx->sample_fmt;
2646 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2648 sink = is->out_audio_filter;
2649 sample_rate = av_buffersink_get_sample_rate(sink);
2650 nb_channels = av_buffersink_get_channels(sink);
2651 channel_layout = av_buffersink_get_channel_layout(sink);
2654 sample_rate = avctx->sample_rate;
2655 nb_channels = avctx->channels;
2656 channel_layout = avctx->channel_layout;
2659 /* prepare audio output */
2660 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2662 is->audio_hw_buf_size = ret;
2663 is->audio_src = is->audio_tgt;
2664 is->audio_buf_size = 0;
2665 is->audio_buf_index = 0;
2667 /* init averaging filter */
2668 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2669 is->audio_diff_avg_count = 0;
2670 /* since we do not have a precise anough audio FIFO fullness,
2671 we correct audio sync only if larger than this threshold */
2672 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2674 is->audio_stream = stream_index;
2675 is->audio_st = ic->streams[stream_index];
2677 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2678 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2679 is->auddec.start_pts = is->audio_st->start_time;
2680 is->auddec.start_pts_tb = is->audio_st->time_base;
2682 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2684 SDL_PauseAudioDevice(audio_dev, 0);
2686 case AVMEDIA_TYPE_VIDEO:
2687 is->video_stream = stream_index;
2688 is->video_st = ic->streams[stream_index];
2690 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2691 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2693 is->queue_attachments_req = 1;
2695 case AVMEDIA_TYPE_SUBTITLE:
2696 is->subtitle_stream = stream_index;
2697 is->subtitle_st = ic->streams[stream_index];
2699 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2700 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2709 avcodec_free_context(&avctx);
2711 av_dict_free(&opts);
2716 static int decode_interrupt_cb(void *ctx)
2718 VideoState *is = ctx;
2719 return is->abort_request;
2722 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2723 return stream_id < 0 ||
2724 queue->abort_request ||
2725 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2726 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2729 static int is_realtime(AVFormatContext *s)
2731 if( !strcmp(s->iformat->name, "rtp")
2732 || !strcmp(s->iformat->name, "rtsp")
2733 || !strcmp(s->iformat->name, "sdp")
2737 if(s->pb && ( !strncmp(s->url, "rtp:", 4)
2738 || !strncmp(s->url, "udp:", 4)
2745 /* this thread gets the stream from the disk or the network */
2746 static int read_thread(void *arg)
2748 VideoState *is = arg;
2749 AVFormatContext *ic = NULL;
2751 int st_index[AVMEDIA_TYPE_NB];
2752 AVPacket pkt1, *pkt = &pkt1;
2753 int64_t stream_start_time;
2754 int pkt_in_play_range = 0;
2755 AVDictionaryEntry *t;
2756 SDL_mutex *wait_mutex = SDL_CreateMutex();
2757 int scan_all_pmts_set = 0;
2761 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2762 ret = AVERROR(ENOMEM);
2766 memset(st_index, -1, sizeof(st_index));
2767 is->last_video_stream = is->video_stream = -1;
2768 is->last_audio_stream = is->audio_stream = -1;
2769 is->last_subtitle_stream = is->subtitle_stream = -1;
2772 ic = avformat_alloc_context();
2774 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2775 ret = AVERROR(ENOMEM);
2778 ic->interrupt_callback.callback = decode_interrupt_cb;
2779 ic->interrupt_callback.opaque = is;
2780 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2781 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2782 scan_all_pmts_set = 1;
2784 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2786 print_error(is->filename, err);
2790 if (scan_all_pmts_set)
2791 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2793 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2794 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2795 ret = AVERROR_OPTION_NOT_FOUND;
2801 ic->flags |= AVFMT_FLAG_GENPTS;
2803 av_format_inject_global_side_data(ic);
2805 if (find_stream_info) {
2806 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2807 int orig_nb_streams = ic->nb_streams;
2809 err = avformat_find_stream_info(ic, opts);
2811 for (i = 0; i < orig_nb_streams; i++)
2812 av_dict_free(&opts[i]);
2816 av_log(NULL, AV_LOG_WARNING,
2817 "%s: could not find codec parameters\n", is->filename);
2824 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2826 if (seek_by_bytes < 0)
2827 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2829 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2831 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2832 window_title = av_asprintf("%s - %s", t->value, input_filename);
2834 /* if seeking requested, we execute it */
2835 if (start_time != AV_NOPTS_VALUE) {
2838 timestamp = start_time;
2839 /* add the stream start time */
2840 if (ic->start_time != AV_NOPTS_VALUE)
2841 timestamp += ic->start_time;
2842 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2844 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2845 is->filename, (double)timestamp / AV_TIME_BASE);
2849 is->realtime = is_realtime(ic);
2852 av_dump_format(ic, 0, is->filename, 0);
2854 for (i = 0; i < ic->nb_streams; i++) {
2855 AVStream *st = ic->streams[i];
2856 enum AVMediaType type = st->codecpar->codec_type;
2857 st->discard = AVDISCARD_ALL;
2858 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2859 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2862 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2863 if (wanted_stream_spec[i] && st_index[i] == -1) {
2864 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));
2865 st_index[i] = INT_MAX;
2870 st_index[AVMEDIA_TYPE_VIDEO] =
2871 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2872 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2874 st_index[AVMEDIA_TYPE_AUDIO] =
2875 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2876 st_index[AVMEDIA_TYPE_AUDIO],
2877 st_index[AVMEDIA_TYPE_VIDEO],
2879 if (!video_disable && !subtitle_disable)
2880 st_index[AVMEDIA_TYPE_SUBTITLE] =
2881 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2882 st_index[AVMEDIA_TYPE_SUBTITLE],
2883 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2884 st_index[AVMEDIA_TYPE_AUDIO] :
2885 st_index[AVMEDIA_TYPE_VIDEO]),
2888 is->show_mode = show_mode;
2889 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2890 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2891 AVCodecParameters *codecpar = st->codecpar;
2892 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2893 if (codecpar->width)
2894 set_default_window_size(codecpar->width, codecpar->height, sar);
2897 /* open the streams */
2898 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2899 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2903 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2904 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2906 if (is->show_mode == SHOW_MODE_NONE)
2907 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2909 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2910 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2913 if (is->video_stream < 0 && is->audio_stream < 0) {
2914 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2920 if (infinite_buffer < 0 && is->realtime)
2921 infinite_buffer = 1;
2924 if (is->abort_request)
2926 if (is->paused != is->last_paused) {
2927 is->last_paused = is->paused;
2929 is->read_pause_return = av_read_pause(ic);
2933 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2935 (!strcmp(ic->iformat->name, "rtsp") ||
2936 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2937 /* wait 10 ms to avoid trying to get another packet */
2944 int64_t seek_target = is->seek_pos;
2945 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2946 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2947 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2948 // of the seek_pos/seek_rel variables
2950 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2952 av_log(NULL, AV_LOG_ERROR,
2953 "%s: error while seeking\n", is->ic->url);
2955 if (is->audio_stream >= 0) {
2956 packet_queue_flush(&is->audioq);
2957 packet_queue_put(&is->audioq, &flush_pkt);
2959 if (is->subtitle_stream >= 0) {
2960 packet_queue_flush(&is->subtitleq);
2961 packet_queue_put(&is->subtitleq, &flush_pkt);
2963 if (is->video_stream >= 0) {
2964 packet_queue_flush(&is->videoq);
2965 packet_queue_put(&is->videoq, &flush_pkt);
2967 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2968 set_clock(&is->extclk, NAN, 0);
2970 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2974 is->queue_attachments_req = 1;
2977 step_to_next_frame(is);
2979 if (is->queue_attachments_req) {
2980 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2981 AVPacket copy = { 0 };
2982 if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0)
2984 packet_queue_put(&is->videoq, ©);
2985 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2987 is->queue_attachments_req = 0;
2990 /* if the queue are full, no need to read more */
2991 if (infinite_buffer<1 &&
2992 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2993 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2994 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2995 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2997 SDL_LockMutex(wait_mutex);
2998 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2999 SDL_UnlockMutex(wait_mutex);
3003 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3004 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3005 if (loop != 1 && (!loop || --loop)) {
3006 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3007 } else if (autoexit) {
3012 ret = av_read_frame(ic, pkt);
3014 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3015 if (is->video_stream >= 0)
3016 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3017 if (is->audio_stream >= 0)
3018 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3019 if (is->subtitle_stream >= 0)
3020 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3023 if (ic->pb && ic->pb->error)
3025 SDL_LockMutex(wait_mutex);
3026 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3027 SDL_UnlockMutex(wait_mutex);
3032 /* check if packet is in play range specified by user, then queue, otherwise discard */
3033 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3034 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3035 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3036 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3037 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3038 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3039 <= ((double)duration / 1000000);
3040 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3041 packet_queue_put(&is->audioq, pkt);
3042 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3043 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3044 packet_queue_put(&is->videoq, pkt);
3045 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3046 packet_queue_put(&is->subtitleq, pkt);
3048 av_packet_unref(pkt);
3055 avformat_close_input(&ic);
3060 event.type = FF_QUIT_EVENT;
3061 event.user.data1 = is;
3062 SDL_PushEvent(&event);
3064 SDL_DestroyMutex(wait_mutex);
3068 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3072 is = av_mallocz(sizeof(VideoState));
3075 is->filename = av_strdup(filename);
3078 is->iformat = iformat;
3082 /* start video display */
3083 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3085 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3087 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3090 if (packet_queue_init(&is->videoq) < 0 ||
3091 packet_queue_init(&is->audioq) < 0 ||
3092 packet_queue_init(&is->subtitleq) < 0)
3095 if (!(is->continue_read_thread = SDL_CreateCond())) {
3096 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3100 init_clock(&is->vidclk, &is->videoq.serial);
3101 init_clock(&is->audclk, &is->audioq.serial);
3102 init_clock(&is->extclk, &is->extclk.serial);
3103 is->audio_clock_serial = -1;
3104 if (startup_volume < 0)
3105 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3106 if (startup_volume > 100)
3107 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3108 startup_volume = av_clip(startup_volume, 0, 100);
3109 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3110 is->audio_volume = startup_volume;
3112 is->av_sync_type = av_sync_type;
3113 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3114 if (!is->read_tid) {
3115 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3123 static void stream_cycle_channel(VideoState *is, int codec_type)
3125 AVFormatContext *ic = is->ic;
3126 int start_index, stream_index;
3129 AVProgram *p = NULL;
3130 int nb_streams = is->ic->nb_streams;
3132 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3133 start_index = is->last_video_stream;
3134 old_index = is->video_stream;
3135 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3136 start_index = is->last_audio_stream;
3137 old_index = is->audio_stream;
3139 start_index = is->last_subtitle_stream;
3140 old_index = is->subtitle_stream;
3142 stream_index = start_index;
3144 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3145 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3147 nb_streams = p->nb_stream_indexes;
3148 for (start_index = 0; start_index < nb_streams; start_index++)
3149 if (p->stream_index[start_index] == stream_index)
3151 if (start_index == nb_streams)
3153 stream_index = start_index;
3158 if (++stream_index >= nb_streams)
3160 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3163 is->last_subtitle_stream = -1;
3166 if (start_index == -1)
3170 if (stream_index == start_index)
3172 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3173 if (st->codecpar->codec_type == codec_type) {
3174 /* check that parameters are OK */
3175 switch (codec_type) {
3176 case AVMEDIA_TYPE_AUDIO:
3177 if (st->codecpar->sample_rate != 0 &&
3178 st->codecpar->channels != 0)
3181 case AVMEDIA_TYPE_VIDEO:
3182 case AVMEDIA_TYPE_SUBTITLE:
3190 if (p && stream_index != -1)
3191 stream_index = p->stream_index[stream_index];
3192 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3193 av_get_media_type_string(codec_type),
3197 stream_component_close(is, old_index);
3198 stream_component_open(is, stream_index);
3202 static void toggle_full_screen(VideoState *is)
3204 is_full_screen = !is_full_screen;
3205 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3208 static void toggle_audio_display(VideoState *is)
3210 int next = is->show_mode;
3212 next = (next + 1) % SHOW_MODE_NB;
3213 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3214 if (is->show_mode != next) {
3215 is->force_refresh = 1;
3216 is->show_mode = next;
3220 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3221 double remaining_time = 0.0;
3223 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3224 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3228 if (remaining_time > 0.0)
3229 av_usleep((int64_t)(remaining_time * 1000000.0));
3230 remaining_time = REFRESH_RATE;
3231 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3232 video_refresh(is, &remaining_time);
3237 static void seek_chapter(VideoState *is, int incr)
3239 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3242 if (!is->ic->nb_chapters)
3245 /* find the current chapter */
3246 for (i = 0; i < is->ic->nb_chapters; i++) {
3247 AVChapter *ch = is->ic->chapters[i];
3248 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3256 if (i >= is->ic->nb_chapters)
3259 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3260 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3261 AV_TIME_BASE_Q), 0, 0);
3264 /* handle an event sent by the GUI */
3265 static void event_loop(VideoState *cur_stream)
3268 double incr, pos, frac;
3272 refresh_loop_wait_event(cur_stream, &event);
3273 switch (event.type) {
3275 if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
3276 do_exit(cur_stream);
3279 // If we don't yet have a window, skip all key events, because read_thread might still be initializing...
3280 if (!cur_stream->width)
3282 switch (event.key.keysym.sym) {
3284 toggle_full_screen(cur_stream);
3285 cur_stream->force_refresh = 1;
3289 toggle_pause(cur_stream);
3292 toggle_mute(cur_stream);
3294 case SDLK_KP_MULTIPLY:
3296 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3298 case SDLK_KP_DIVIDE:
3300 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3302 case SDLK_s: // S: Step to next frame
3303 step_to_next_frame(cur_stream);
3306 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3309 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3312 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3313 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3314 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3317 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3321 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3322 if (++cur_stream->vfilter_idx >= nb_vfilters)
3323 cur_stream->vfilter_idx = 0;
3325 cur_stream->vfilter_idx = 0;
3326 toggle_audio_display(cur_stream);
3329 toggle_audio_display(cur_stream);
3333 if (cur_stream->ic->nb_chapters <= 1) {
3337 seek_chapter(cur_stream, 1);
3340 if (cur_stream->ic->nb_chapters <= 1) {
3344 seek_chapter(cur_stream, -1);
3347 incr = seek_interval ? -seek_interval : -10.0;
3350 incr = seek_interval ? seek_interval : 10.0;
3358 if (seek_by_bytes) {
3360 if (pos < 0 && cur_stream->video_stream >= 0)
3361 pos = frame_queue_last_pos(&cur_stream->pictq);
3362 if (pos < 0 && cur_stream->audio_stream >= 0)
3363 pos = frame_queue_last_pos(&cur_stream->sampq);
3365 pos = avio_tell(cur_stream->ic->pb);
3366 if (cur_stream->ic->bit_rate)
3367 incr *= cur_stream->ic->bit_rate / 8.0;
3371 stream_seek(cur_stream, pos, incr, 1);
3373 pos = get_master_clock(cur_stream);
3375 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3377 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3378 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3379 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3386 case SDL_MOUSEBUTTONDOWN:
3387 if (exit_on_mousedown) {
3388 do_exit(cur_stream);
3391 if (event.button.button == SDL_BUTTON_LEFT) {
3392 static int64_t last_mouse_left_click = 0;
3393 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3394 toggle_full_screen(cur_stream);
3395 cur_stream->force_refresh = 1;
3396 last_mouse_left_click = 0;
3398 last_mouse_left_click = av_gettime_relative();
3401 case SDL_MOUSEMOTION:
3402 if (cursor_hidden) {
3406 cursor_last_shown = av_gettime_relative();
3407 if (event.type == SDL_MOUSEBUTTONDOWN) {
3408 if (event.button.button != SDL_BUTTON_RIGHT)
3412 if (!(event.motion.state & SDL_BUTTON_RMASK))
3416 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3417 uint64_t size = avio_size(cur_stream->ic->pb);
3418 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3422 int tns, thh, tmm, tss;
3423 tns = cur_stream->ic->duration / 1000000LL;
3425 tmm = (tns % 3600) / 60;
3427 frac = x / cur_stream->width;
3430 mm = (ns % 3600) / 60;
3432 av_log(NULL, AV_LOG_INFO,
3433 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3434 hh, mm, ss, thh, tmm, tss);
3435 ts = frac * cur_stream->ic->duration;
3436 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3437 ts += cur_stream->ic->start_time;
3438 stream_seek(cur_stream, ts, 0, 0);
3441 case SDL_WINDOWEVENT:
3442 switch (event.window.event) {
3443 case SDL_WINDOWEVENT_RESIZED:
3444 screen_width = cur_stream->width = event.window.data1;
3445 screen_height = cur_stream->height = event.window.data2;
3446 if (cur_stream->vis_texture) {
3447 SDL_DestroyTexture(cur_stream->vis_texture);
3448 cur_stream->vis_texture = NULL;
3450 case SDL_WINDOWEVENT_EXPOSED:
3451 cur_stream->force_refresh = 1;
3456 do_exit(cur_stream);
3464 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3466 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3467 return opt_default(NULL, "video_size", arg);
3470 static int opt_width(void *optctx, const char *opt, const char *arg)
3472 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3476 static int opt_height(void *optctx, const char *opt, const char *arg)
3478 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3482 static int opt_format(void *optctx, const char *opt, const char *arg)
3484 file_iformat = av_find_input_format(arg);
3485 if (!file_iformat) {
3486 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3487 return AVERROR(EINVAL);
3492 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3494 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3495 return opt_default(NULL, "pixel_format", arg);
3498 static int opt_sync(void *optctx, const char *opt, const char *arg)
3500 if (!strcmp(arg, "audio"))
3501 av_sync_type = AV_SYNC_AUDIO_MASTER;
3502 else if (!strcmp(arg, "video"))
3503 av_sync_type = AV_SYNC_VIDEO_MASTER;
3504 else if (!strcmp(arg, "ext"))
3505 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3507 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3513 static int opt_seek(void *optctx, const char *opt, const char *arg)
3515 start_time = parse_time_or_die(opt, arg, 1);
3519 static int opt_duration(void *optctx, const char *opt, const char *arg)
3521 duration = parse_time_or_die(opt, arg, 1);
3525 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3527 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3528 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3529 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3530 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3534 static void opt_input_file(void *optctx, const char *filename)
3536 if (input_filename) {
3537 av_log(NULL, AV_LOG_FATAL,
3538 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3539 filename, input_filename);
3542 if (!strcmp(filename, "-"))
3544 input_filename = filename;
3547 static int opt_codec(void *optctx, const char *opt, const char *arg)
3549 const char *spec = strchr(opt, ':');
3551 av_log(NULL, AV_LOG_ERROR,
3552 "No media specifier was specified in '%s' in option '%s'\n",
3554 return AVERROR(EINVAL);
3558 case 'a' : audio_codec_name = arg; break;
3559 case 's' : subtitle_codec_name = arg; break;
3560 case 'v' : video_codec_name = arg; break;
3562 av_log(NULL, AV_LOG_ERROR,
3563 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3564 return AVERROR(EINVAL);
3571 static const OptionDef options[] = {
3572 CMDUTILS_COMMON_OPTIONS
3573 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3574 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3575 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3576 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3577 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3578 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3579 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3580 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3581 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3582 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3583 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3584 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3585 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3586 { "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
3587 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3588 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3589 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3590 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3591 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3592 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3593 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3594 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3595 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3596 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3597 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3598 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3599 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3600 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3601 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3602 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3603 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3604 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3606 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3607 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3609 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3610 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3611 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3612 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3613 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3614 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3615 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3616 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3617 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3618 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3619 "read and decode the streams to fill missing information with heuristics" },
3623 static void show_usage(void)
3625 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3626 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3627 av_log(NULL, AV_LOG_INFO, "\n");
3630 void show_help_default(const char *opt, const char *arg)
3632 av_log_set_callback(log_callback_help);
3634 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3635 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3637 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3638 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3639 #if !CONFIG_AVFILTER
3640 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3642 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3644 printf("\nWhile playing:\n"
3646 "f toggle full screen\n"
3649 "9, 0 decrease and increase volume respectively\n"
3650 "/, * decrease and increase volume respectively\n"
3651 "a cycle audio channel in the current program\n"
3652 "v cycle video channel\n"
3653 "t cycle subtitle channel in the current program\n"
3655 "w cycle video filters or show modes\n"
3656 "s activate frame-step mode\n"
3657 "left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
3658 "down/up seek backward/forward 1 minute\n"
3659 "page down/page up seek backward/forward 10 minutes\n"
3660 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3661 "left double-click toggle full screen\n"
3665 /* Called from the main */
3666 int main(int argc, char **argv)
3673 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3674 parse_loglevel(argc, argv, options);
3676 /* register all codecs, demux and protocols */
3678 avdevice_register_all();
3680 avformat_network_init();
3684 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3685 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3687 show_banner(argc, argv, options);
3689 parse_options(NULL, argc, argv, options, opt_input_file);
3691 if (!input_filename) {
3693 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3694 av_log(NULL, AV_LOG_FATAL,
3695 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3699 if (display_disable) {
3702 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3704 flags &= ~SDL_INIT_AUDIO;
3706 /* Try to work around an occasional ALSA buffer underflow issue when the
3707 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3708 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3709 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3711 if (display_disable)
3712 flags &= ~SDL_INIT_VIDEO;
3713 if (SDL_Init (flags)) {
3714 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3715 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3719 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3720 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3722 av_init_packet(&flush_pkt);
3723 flush_pkt.data = (uint8_t *)&flush_pkt;
3725 if (!display_disable) {
3726 int flags = SDL_WINDOW_HIDDEN;
3728 flags |= SDL_WINDOW_BORDERLESS;
3730 flags |= SDL_WINDOW_RESIZABLE;
3731 window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
3732 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
3734 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
3736 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
3737 renderer = SDL_CreateRenderer(window, -1, 0);
3740 if (!SDL_GetRendererInfo(renderer, &renderer_info))
3741 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
3744 if (!window || !renderer || !renderer_info.num_texture_formats) {
3745 av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
3750 is = stream_open(input_filename, file_iformat);
3752 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");