2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control in dB */
77 #define SDL_VOLUME_STEP (0.75)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
110 static unsigned sws_flags = SWS_BICUBIC;
112 typedef struct MyAVPacketList {
114 struct MyAVPacketList *next;
118 typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
134 typedef struct AudioParams {
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
143 typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
148 int serial; /* clock is based on a packet with this serial */
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
169 typedef struct FrameQueue {
170 Frame queue[FRAME_QUEUE_SIZE];
183 AV_SYNC_AUDIO_MASTER, /* default choice */
184 AV_SYNC_VIDEO_MASTER,
185 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
188 typedef struct Decoder {
191 AVCodecContext *avctx;
195 SDL_cond *empty_queue_cond;
197 AVRational start_pts_tb;
199 AVRational next_pts_tb;
200 SDL_Thread *decoder_tid;
203 typedef struct VideoState {
204 SDL_Thread *read_tid;
205 AVInputFormat *iformat;
210 int queue_attachments_req;
215 int read_pause_return;
236 int audio_clock_serial;
237 double audio_diff_cum; /* used for AV difference average computation */
238 double audio_diff_avg_coef;
239 double audio_diff_threshold;
240 int audio_diff_avg_count;
243 int audio_hw_buf_size;
246 unsigned int audio_buf_size; /* in bytes */
247 unsigned int audio_buf1_size;
248 int audio_buf_index; /* in bytes */
249 int audio_write_buf_size;
252 struct AudioParams audio_src;
254 struct AudioParams audio_filter_src;
256 struct AudioParams audio_tgt;
257 struct SwrContext *swr_ctx;
258 int frame_drops_early;
259 int frame_drops_late;
262 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
264 int16_t sample_array[SAMPLE_ARRAY_SIZE];
265 int sample_array_index;
269 FFTSample *rdft_data;
271 double last_vis_time;
272 SDL_Texture *vis_texture;
273 SDL_Texture *sub_texture;
274 SDL_Texture *vid_texture;
277 AVStream *subtitle_st;
278 PacketQueue subtitleq;
281 double frame_last_returned_time;
282 double frame_last_filter_delay;
286 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
287 struct SwsContext *img_convert_ctx;
288 struct SwsContext *sub_convert_ctx;
292 int width, height, xleft, ytop;
297 AVFilterContext *in_video_filter; // the first filter in the video chain
298 AVFilterContext *out_video_filter; // the last filter in the video chain
299 AVFilterContext *in_audio_filter; // the first filter in the audio chain
300 AVFilterContext *out_audio_filter; // the last filter in the audio chain
301 AVFilterGraph *agraph; // audio filter graph
304 int last_video_stream, last_audio_stream, last_subtitle_stream;
306 SDL_cond *continue_read_thread;
309 /* options specified by the user */
310 static AVInputFormat *file_iformat;
311 static const char *input_filename;
312 static const char *window_title;
313 static int default_width = 640;
314 static int default_height = 480;
315 static int screen_width = 0;
316 static int screen_height = 0;
317 static int screen_left = SDL_WINDOWPOS_CENTERED;
318 static int screen_top = SDL_WINDOWPOS_CENTERED;
319 static int audio_disable;
320 static int video_disable;
321 static int subtitle_disable;
322 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
323 static int seek_by_bytes = -1;
324 static float seek_interval = 10;
325 static int display_disable;
326 static int borderless;
327 static int startup_volume = 100;
328 static int show_status = 1;
329 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
330 static int64_t start_time = AV_NOPTS_VALUE;
331 static int64_t duration = AV_NOPTS_VALUE;
333 static int genpts = 0;
334 static int lowres = 0;
335 static int decoder_reorder_pts = -1;
337 static int exit_on_keydown;
338 static int exit_on_mousedown;
340 static int framedrop = -1;
341 static int infinite_buffer = -1;
342 static enum ShowMode show_mode = SHOW_MODE_NONE;
343 static const char *audio_codec_name;
344 static const char *subtitle_codec_name;
345 static const char *video_codec_name;
346 double rdftspeed = 0.02;
347 static int64_t cursor_last_shown;
348 static int cursor_hidden = 0;
350 static const char **vfilters_list = NULL;
351 static int nb_vfilters = 0;
352 static char *afilters = NULL;
354 static int autorotate = 1;
355 static int find_stream_info = 1;
357 /* current context */
358 static int is_full_screen;
359 static int64_t audio_callback_time;
361 static AVPacket flush_pkt;
363 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
365 static SDL_Window *window;
366 static SDL_Renderer *renderer;
367 static SDL_RendererInfo renderer_info = {0};
368 static SDL_AudioDeviceID audio_dev;
370 static const struct TextureFormatEntry {
371 enum AVPixelFormat format;
373 } sdl_texture_format_map[] = {
374 { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 },
375 { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 },
376 { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 },
377 { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 },
378 { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 },
379 { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 },
380 { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 },
381 { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 },
382 { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 },
383 { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 },
384 { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 },
385 { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 },
386 { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 },
387 { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 },
388 { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 },
389 { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 },
390 { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV },
391 { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 },
392 { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY },
393 { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN },
397 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
399 GROW_ARRAY(vfilters_list, nb_vfilters);
400 vfilters_list[nb_vfilters - 1] = arg;
406 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
407 enum AVSampleFormat fmt2, int64_t channel_count2)
409 /* If channel count == 1, planar and non-planar formats are the same */
410 if (channel_count1 == 1 && channel_count2 == 1)
411 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
413 return channel_count1 != channel_count2 || fmt1 != fmt2;
417 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
419 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
420 return channel_layout;
425 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
427 MyAVPacketList *pkt1;
429 if (q->abort_request)
432 pkt1 = av_malloc(sizeof(MyAVPacketList));
437 if (pkt == &flush_pkt)
439 pkt1->serial = q->serial;
444 q->last_pkt->next = pkt1;
447 q->size += pkt1->pkt.size + sizeof(*pkt1);
448 q->duration += pkt1->pkt.duration;
449 /* XXX: should duplicate packet data in DV case */
450 SDL_CondSignal(q->cond);
454 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
458 SDL_LockMutex(q->mutex);
459 ret = packet_queue_put_private(q, pkt);
460 SDL_UnlockMutex(q->mutex);
462 if (pkt != &flush_pkt && ret < 0)
463 av_packet_unref(pkt);
468 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
470 AVPacket pkt1, *pkt = &pkt1;
474 pkt->stream_index = stream_index;
475 return packet_queue_put(q, pkt);
478 /* packet queue handling */
479 static int packet_queue_init(PacketQueue *q)
481 memset(q, 0, sizeof(PacketQueue));
482 q->mutex = SDL_CreateMutex();
484 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
485 return AVERROR(ENOMEM);
487 q->cond = SDL_CreateCond();
489 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
490 return AVERROR(ENOMEM);
492 q->abort_request = 1;
496 static void packet_queue_flush(PacketQueue *q)
498 MyAVPacketList *pkt, *pkt1;
500 SDL_LockMutex(q->mutex);
501 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
503 av_packet_unref(&pkt->pkt);
511 SDL_UnlockMutex(q->mutex);
514 static void packet_queue_destroy(PacketQueue *q)
516 packet_queue_flush(q);
517 SDL_DestroyMutex(q->mutex);
518 SDL_DestroyCond(q->cond);
521 static void packet_queue_abort(PacketQueue *q)
523 SDL_LockMutex(q->mutex);
525 q->abort_request = 1;
527 SDL_CondSignal(q->cond);
529 SDL_UnlockMutex(q->mutex);
532 static void packet_queue_start(PacketQueue *q)
534 SDL_LockMutex(q->mutex);
535 q->abort_request = 0;
536 packet_queue_put_private(q, &flush_pkt);
537 SDL_UnlockMutex(q->mutex);
540 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
541 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
543 MyAVPacketList *pkt1;
546 SDL_LockMutex(q->mutex);
549 if (q->abort_request) {
556 q->first_pkt = pkt1->next;
560 q->size -= pkt1->pkt.size + sizeof(*pkt1);
561 q->duration -= pkt1->pkt.duration;
564 *serial = pkt1->serial;
572 SDL_CondWait(q->cond, q->mutex);
575 SDL_UnlockMutex(q->mutex);
579 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
580 memset(d, 0, sizeof(Decoder));
583 d->empty_queue_cond = empty_queue_cond;
584 d->start_pts = AV_NOPTS_VALUE;
588 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
589 int ret = AVERROR(EAGAIN);
594 if (d->queue->serial == d->pkt_serial) {
596 if (d->queue->abort_request)
599 switch (d->avctx->codec_type) {
600 case AVMEDIA_TYPE_VIDEO:
601 ret = avcodec_receive_frame(d->avctx, frame);
603 if (decoder_reorder_pts == -1) {
604 frame->pts = frame->best_effort_timestamp;
605 } else if (!decoder_reorder_pts) {
606 frame->pts = frame->pkt_dts;
610 case AVMEDIA_TYPE_AUDIO:
611 ret = avcodec_receive_frame(d->avctx, frame);
613 AVRational tb = (AVRational){1, frame->sample_rate};
614 if (frame->pts != AV_NOPTS_VALUE)
615 frame->pts = av_rescale_q(frame->pts, d->avctx->pkt_timebase, tb);
616 else if (d->next_pts != AV_NOPTS_VALUE)
617 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
618 if (frame->pts != AV_NOPTS_VALUE) {
619 d->next_pts = frame->pts + frame->nb_samples;
625 if (ret == AVERROR_EOF) {
626 d->finished = d->pkt_serial;
627 avcodec_flush_buffers(d->avctx);
632 } while (ret != AVERROR(EAGAIN));
636 if (d->queue->nb_packets == 0)
637 SDL_CondSignal(d->empty_queue_cond);
638 if (d->packet_pending) {
639 av_packet_move_ref(&pkt, &d->pkt);
640 d->packet_pending = 0;
642 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
645 } while (d->queue->serial != d->pkt_serial);
647 if (pkt.data == flush_pkt.data) {
648 avcodec_flush_buffers(d->avctx);
650 d->next_pts = d->start_pts;
651 d->next_pts_tb = d->start_pts_tb;
653 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
655 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
657 ret = AVERROR(EAGAIN);
659 if (got_frame && !pkt.data) {
660 d->packet_pending = 1;
661 av_packet_move_ref(&d->pkt, &pkt);
663 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
666 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
667 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
668 d->packet_pending = 1;
669 av_packet_move_ref(&d->pkt, &pkt);
672 av_packet_unref(&pkt);
677 static void decoder_destroy(Decoder *d) {
678 av_packet_unref(&d->pkt);
679 avcodec_free_context(&d->avctx);
682 static void frame_queue_unref_item(Frame *vp)
684 av_frame_unref(vp->frame);
685 avsubtitle_free(&vp->sub);
688 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
691 memset(f, 0, sizeof(FrameQueue));
692 if (!(f->mutex = SDL_CreateMutex())) {
693 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
694 return AVERROR(ENOMEM);
696 if (!(f->cond = SDL_CreateCond())) {
697 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
698 return AVERROR(ENOMEM);
701 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
702 f->keep_last = !!keep_last;
703 for (i = 0; i < f->max_size; i++)
704 if (!(f->queue[i].frame = av_frame_alloc()))
705 return AVERROR(ENOMEM);
709 static void frame_queue_destory(FrameQueue *f)
712 for (i = 0; i < f->max_size; i++) {
713 Frame *vp = &f->queue[i];
714 frame_queue_unref_item(vp);
715 av_frame_free(&vp->frame);
717 SDL_DestroyMutex(f->mutex);
718 SDL_DestroyCond(f->cond);
721 static void frame_queue_signal(FrameQueue *f)
723 SDL_LockMutex(f->mutex);
724 SDL_CondSignal(f->cond);
725 SDL_UnlockMutex(f->mutex);
728 static Frame *frame_queue_peek(FrameQueue *f)
730 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
733 static Frame *frame_queue_peek_next(FrameQueue *f)
735 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
738 static Frame *frame_queue_peek_last(FrameQueue *f)
740 return &f->queue[f->rindex];
743 static Frame *frame_queue_peek_writable(FrameQueue *f)
745 /* wait until we have space to put a new frame */
746 SDL_LockMutex(f->mutex);
747 while (f->size >= f->max_size &&
748 !f->pktq->abort_request) {
749 SDL_CondWait(f->cond, f->mutex);
751 SDL_UnlockMutex(f->mutex);
753 if (f->pktq->abort_request)
756 return &f->queue[f->windex];
759 static Frame *frame_queue_peek_readable(FrameQueue *f)
761 /* wait until we have a readable a new frame */
762 SDL_LockMutex(f->mutex);
763 while (f->size - f->rindex_shown <= 0 &&
764 !f->pktq->abort_request) {
765 SDL_CondWait(f->cond, f->mutex);
767 SDL_UnlockMutex(f->mutex);
769 if (f->pktq->abort_request)
772 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
775 static void frame_queue_push(FrameQueue *f)
777 if (++f->windex == f->max_size)
779 SDL_LockMutex(f->mutex);
781 SDL_CondSignal(f->cond);
782 SDL_UnlockMutex(f->mutex);
785 static void frame_queue_next(FrameQueue *f)
787 if (f->keep_last && !f->rindex_shown) {
791 frame_queue_unref_item(&f->queue[f->rindex]);
792 if (++f->rindex == f->max_size)
794 SDL_LockMutex(f->mutex);
796 SDL_CondSignal(f->cond);
797 SDL_UnlockMutex(f->mutex);
800 /* return the number of undisplayed frames in the queue */
801 static int frame_queue_nb_remaining(FrameQueue *f)
803 return f->size - f->rindex_shown;
806 /* return last shown position */
807 static int64_t frame_queue_last_pos(FrameQueue *f)
809 Frame *fp = &f->queue[f->rindex];
810 if (f->rindex_shown && fp->serial == f->pktq->serial)
816 static void decoder_abort(Decoder *d, FrameQueue *fq)
818 packet_queue_abort(d->queue);
819 frame_queue_signal(fq);
820 SDL_WaitThread(d->decoder_tid, NULL);
821 d->decoder_tid = NULL;
822 packet_queue_flush(d->queue);
825 static inline void fill_rectangle(int x, int y, int w, int h)
833 SDL_RenderFillRect(renderer, &rect);
836 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
840 if (!*texture || SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
844 SDL_DestroyTexture(*texture);
845 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
847 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
850 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
852 memset(pixels, 0, pitch * new_height);
853 SDL_UnlockTexture(*texture);
855 av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
860 static void calculate_display_rect(SDL_Rect *rect,
861 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
862 int pic_width, int pic_height, AVRational pic_sar)
864 AVRational aspect_ratio = pic_sar;
865 int64_t width, height, x, y;
867 if (av_cmp_q(aspect_ratio, av_make_q(0, 1)) <= 0)
868 aspect_ratio = av_make_q(1, 1);
870 aspect_ratio = av_mul_q(aspect_ratio, av_make_q(pic_width, pic_height));
872 /* XXX: we suppose the screen has a 1.0 pixel ratio */
874 width = av_rescale(height, aspect_ratio.num, aspect_ratio.den) & ~1;
875 if (width > scr_width) {
877 height = av_rescale(width, aspect_ratio.den, aspect_ratio.num) & ~1;
879 x = (scr_width - width) / 2;
880 y = (scr_height - height) / 2;
881 rect->x = scr_xleft + x;
882 rect->y = scr_ytop + y;
883 rect->w = FFMAX((int)width, 1);
884 rect->h = FFMAX((int)height, 1);
887 static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
890 *sdl_blendmode = SDL_BLENDMODE_NONE;
891 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
892 if (format == AV_PIX_FMT_RGB32 ||
893 format == AV_PIX_FMT_RGB32_1 ||
894 format == AV_PIX_FMT_BGR32 ||
895 format == AV_PIX_FMT_BGR32_1)
896 *sdl_blendmode = SDL_BLENDMODE_BLEND;
897 for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
898 if (format == sdl_texture_format_map[i].format) {
899 *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
905 static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
908 SDL_BlendMode sdl_blendmode;
909 get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
910 if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
912 switch (sdl_pix_fmt) {
913 case SDL_PIXELFORMAT_UNKNOWN:
914 /* This should only happen if we are not using avfilter... */
915 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
916 frame->width, frame->height, frame->format, frame->width, frame->height,
917 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
918 if (*img_convert_ctx != NULL) {
921 if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
922 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
923 0, frame->height, pixels, pitch);
924 SDL_UnlockTexture(*tex);
927 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
931 case SDL_PIXELFORMAT_IYUV:
932 if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
933 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
934 frame->data[1], frame->linesize[1],
935 frame->data[2], frame->linesize[2]);
936 } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) {
937 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0],
938 frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
939 frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
941 av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
946 if (frame->linesize[0] < 0) {
947 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
949 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
956 static void set_sdl_yuv_conversion_mode(AVFrame *frame)
958 #if SDL_VERSION_ATLEAST(2,0,8)
959 SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
960 if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
961 if (frame->color_range == AVCOL_RANGE_JPEG)
962 mode = SDL_YUV_CONVERSION_JPEG;
963 else if (frame->colorspace == AVCOL_SPC_BT709)
964 mode = SDL_YUV_CONVERSION_BT709;
965 else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
966 mode = SDL_YUV_CONVERSION_BT601;
968 SDL_SetYUVConversionMode(mode);
972 static void video_image_display(VideoState *is)
978 vp = frame_queue_peek_last(&is->pictq);
979 if (is->subtitle_st) {
980 if (frame_queue_nb_remaining(&is->subpq) > 0) {
981 sp = frame_queue_peek(&is->subpq);
983 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
988 if (!sp->width || !sp->height) {
989 sp->width = vp->width;
990 sp->height = vp->height;
992 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
995 for (i = 0; i < sp->sub.num_rects; i++) {
996 AVSubtitleRect *sub_rect = sp->sub.rects[i];
998 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
999 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
1000 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
1001 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
1003 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
1004 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
1005 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
1006 0, NULL, NULL, NULL);
1007 if (!is->sub_convert_ctx) {
1008 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1011 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
1012 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
1013 0, sub_rect->h, pixels, pitch);
1014 SDL_UnlockTexture(is->sub_texture);
1024 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1026 if (!vp->uploaded) {
1027 if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
1030 vp->flip_v = vp->frame->linesize[0] < 0;
1033 set_sdl_yuv_conversion_mode(vp->frame);
1034 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
1035 set_sdl_yuv_conversion_mode(NULL);
1037 #if USE_ONEPASS_SUBTITLE_RENDER
1038 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
1041 double xratio = (double)rect.w / (double)sp->width;
1042 double yratio = (double)rect.h / (double)sp->height;
1043 for (i = 0; i < sp->sub.num_rects; i++) {
1044 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
1045 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
1046 .y = rect.y + sub_rect->y * yratio,
1047 .w = sub_rect->w * xratio,
1048 .h = sub_rect->h * yratio};
1049 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
1055 static inline int compute_mod(int a, int b)
1057 return a < 0 ? a%b + b : a%b;
1060 static void video_audio_display(VideoState *s)
1062 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1063 int ch, channels, h, h2;
1065 int rdft_bits, nb_freq;
1067 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1069 nb_freq = 1 << (rdft_bits - 1);
1071 /* compute display index : center on currently output samples */
1072 channels = s->audio_tgt.channels;
1073 nb_display_channels = channels;
1075 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1077 delay = s->audio_write_buf_size;
1080 /* to be more precise, we take into account the time spent since
1081 the last buffer computation */
1082 if (audio_callback_time) {
1083 time_diff = av_gettime_relative() - audio_callback_time;
1084 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1087 delay += 2 * data_used;
1088 if (delay < data_used)
1091 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1092 if (s->show_mode == SHOW_MODE_WAVES) {
1094 for (i = 0; i < 1000; i += channels) {
1095 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1096 int a = s->sample_array[idx];
1097 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1098 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1099 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1101 if (h < score && (b ^ c) < 0) {
1108 s->last_i_start = i_start;
1110 i_start = s->last_i_start;
1113 if (s->show_mode == SHOW_MODE_WAVES) {
1114 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1116 /* total height for one channel */
1117 h = s->height / nb_display_channels;
1118 /* graph height / 2 */
1120 for (ch = 0; ch < nb_display_channels; ch++) {
1122 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1123 for (x = 0; x < s->width; x++) {
1124 y = (s->sample_array[i] * h2) >> 15;
1131 fill_rectangle(s->xleft + x, ys, 1, y);
1133 if (i >= SAMPLE_ARRAY_SIZE)
1134 i -= SAMPLE_ARRAY_SIZE;
1138 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1140 for (ch = 1; ch < nb_display_channels; ch++) {
1141 y = s->ytop + ch * h;
1142 fill_rectangle(s->xleft, y, s->width, 1);
1145 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1148 nb_display_channels= FFMIN(nb_display_channels, 2);
1149 if (rdft_bits != s->rdft_bits) {
1150 av_rdft_end(s->rdft);
1151 av_free(s->rdft_data);
1152 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1153 s->rdft_bits = rdft_bits;
1154 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1156 if (!s->rdft || !s->rdft_data){
1157 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1158 s->show_mode = SHOW_MODE_WAVES;
1161 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1164 for (ch = 0; ch < nb_display_channels; ch++) {
1165 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1167 for (x = 0; x < 2 * nb_freq; x++) {
1168 double w = (x-nb_freq) * (1.0 / nb_freq);
1169 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1171 if (i >= SAMPLE_ARRAY_SIZE)
1172 i -= SAMPLE_ARRAY_SIZE;
1174 av_rdft_calc(s->rdft, data[ch]);
1176 /* Least efficient way to do this, we should of course
1177 * directly access it but it is more than fast enough. */
1178 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1180 pixels += pitch * s->height;
1181 for (y = 0; y < s->height; y++) {
1182 double w = 1 / sqrt(nb_freq);
1183 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]));
1184 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1189 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1191 SDL_UnlockTexture(s->vis_texture);
1193 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1197 if (s->xpos >= s->width)
1202 static void stream_component_close(VideoState *is, int stream_index)
1204 AVFormatContext *ic = is->ic;
1205 AVCodecParameters *codecpar;
1207 if (stream_index < 0 || stream_index >= ic->nb_streams)
1209 codecpar = ic->streams[stream_index]->codecpar;
1211 switch (codecpar->codec_type) {
1212 case AVMEDIA_TYPE_AUDIO:
1213 decoder_abort(&is->auddec, &is->sampq);
1214 SDL_CloseAudioDevice(audio_dev);
1215 decoder_destroy(&is->auddec);
1216 swr_free(&is->swr_ctx);
1217 av_freep(&is->audio_buf1);
1218 is->audio_buf1_size = 0;
1219 is->audio_buf = NULL;
1222 av_rdft_end(is->rdft);
1223 av_freep(&is->rdft_data);
1228 case AVMEDIA_TYPE_VIDEO:
1229 decoder_abort(&is->viddec, &is->pictq);
1230 decoder_destroy(&is->viddec);
1232 case AVMEDIA_TYPE_SUBTITLE:
1233 decoder_abort(&is->subdec, &is->subpq);
1234 decoder_destroy(&is->subdec);
1240 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1241 switch (codecpar->codec_type) {
1242 case AVMEDIA_TYPE_AUDIO:
1243 is->audio_st = NULL;
1244 is->audio_stream = -1;
1246 case AVMEDIA_TYPE_VIDEO:
1247 is->video_st = NULL;
1248 is->video_stream = -1;
1250 case AVMEDIA_TYPE_SUBTITLE:
1251 is->subtitle_st = NULL;
1252 is->subtitle_stream = -1;
1259 static void stream_close(VideoState *is)
1261 /* XXX: use a special url_shutdown call to abort parse cleanly */
1262 is->abort_request = 1;
1263 SDL_WaitThread(is->read_tid, NULL);
1265 /* close each stream */
1266 if (is->audio_stream >= 0)
1267 stream_component_close(is, is->audio_stream);
1268 if (is->video_stream >= 0)
1269 stream_component_close(is, is->video_stream);
1270 if (is->subtitle_stream >= 0)
1271 stream_component_close(is, is->subtitle_stream);
1273 avformat_close_input(&is->ic);
1275 packet_queue_destroy(&is->videoq);
1276 packet_queue_destroy(&is->audioq);
1277 packet_queue_destroy(&is->subtitleq);
1279 /* free all pictures */
1280 frame_queue_destory(&is->pictq);
1281 frame_queue_destory(&is->sampq);
1282 frame_queue_destory(&is->subpq);
1283 SDL_DestroyCond(is->continue_read_thread);
1284 sws_freeContext(is->img_convert_ctx);
1285 sws_freeContext(is->sub_convert_ctx);
1286 av_free(is->filename);
1287 if (is->vis_texture)
1288 SDL_DestroyTexture(is->vis_texture);
1289 if (is->vid_texture)
1290 SDL_DestroyTexture(is->vid_texture);
1291 if (is->sub_texture)
1292 SDL_DestroyTexture(is->sub_texture);
1296 static void do_exit(VideoState *is)
1302 SDL_DestroyRenderer(renderer);
1304 SDL_DestroyWindow(window);
1307 av_freep(&vfilters_list);
1309 avformat_network_deinit();
1313 av_log(NULL, AV_LOG_QUIET, "%s", "");
1317 static void sigterm_handler(int sig)
1322 static void set_default_window_size(int width, int height, AVRational sar)
1325 int max_width = screen_width ? screen_width : INT_MAX;
1326 int max_height = screen_height ? screen_height : INT_MAX;
1327 if (max_width == INT_MAX && max_height == INT_MAX)
1328 max_height = height;
1329 calculate_display_rect(&rect, 0, 0, max_width, max_height, width, height, sar);
1330 default_width = rect.w;
1331 default_height = rect.h;
1334 static int video_open(VideoState *is)
1338 w = screen_width ? screen_width : default_width;
1339 h = screen_height ? screen_height : default_height;
1342 window_title = input_filename;
1343 SDL_SetWindowTitle(window, window_title);
1345 SDL_SetWindowSize(window, w, h);
1346 SDL_SetWindowPosition(window, screen_left, screen_top);
1348 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1349 SDL_ShowWindow(window);
1357 /* display the current picture, if any */
1358 static void video_display(VideoState *is)
1363 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1364 SDL_RenderClear(renderer);
1365 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1366 video_audio_display(is);
1367 else if (is->video_st)
1368 video_image_display(is);
1369 SDL_RenderPresent(renderer);
1372 static double get_clock(Clock *c)
1374 if (*c->queue_serial != c->serial)
1379 double time = av_gettime_relative() / 1000000.0;
1380 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1384 static void set_clock_at(Clock *c, double pts, int serial, double time)
1387 c->last_updated = time;
1388 c->pts_drift = c->pts - time;
1392 static void set_clock(Clock *c, double pts, int serial)
1394 double time = av_gettime_relative() / 1000000.0;
1395 set_clock_at(c, pts, serial, time);
1398 static void set_clock_speed(Clock *c, double speed)
1400 set_clock(c, get_clock(c), c->serial);
1404 static void init_clock(Clock *c, int *queue_serial)
1408 c->queue_serial = queue_serial;
1409 set_clock(c, NAN, -1);
1412 static void sync_clock_to_slave(Clock *c, Clock *slave)
1414 double clock = get_clock(c);
1415 double slave_clock = get_clock(slave);
1416 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1417 set_clock(c, slave_clock, slave->serial);
1420 static int get_master_sync_type(VideoState *is) {
1421 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1423 return AV_SYNC_VIDEO_MASTER;
1425 return AV_SYNC_AUDIO_MASTER;
1426 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1428 return AV_SYNC_AUDIO_MASTER;
1430 return AV_SYNC_EXTERNAL_CLOCK;
1432 return AV_SYNC_EXTERNAL_CLOCK;
1436 /* get the current master clock value */
1437 static double get_master_clock(VideoState *is)
1441 switch (get_master_sync_type(is)) {
1442 case AV_SYNC_VIDEO_MASTER:
1443 val = get_clock(&is->vidclk);
1445 case AV_SYNC_AUDIO_MASTER:
1446 val = get_clock(&is->audclk);
1449 val = get_clock(&is->extclk);
1455 static void check_external_clock_speed(VideoState *is) {
1456 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1457 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1458 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1459 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1460 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1461 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1463 double speed = is->extclk.speed;
1465 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1469 /* seek in the stream */
1470 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1472 if (!is->seek_req) {
1475 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1477 is->seek_flags |= AVSEEK_FLAG_BYTE;
1479 SDL_CondSignal(is->continue_read_thread);
1483 /* pause or resume the video */
1484 static void stream_toggle_pause(VideoState *is)
1487 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1488 if (is->read_pause_return != AVERROR(ENOSYS)) {
1489 is->vidclk.paused = 0;
1491 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1493 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1494 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1497 static void toggle_pause(VideoState *is)
1499 stream_toggle_pause(is);
1503 static void toggle_mute(VideoState *is)
1505 is->muted = !is->muted;
1508 static void update_volume(VideoState *is, int sign, double step)
1510 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1511 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1512 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1515 static void step_to_next_frame(VideoState *is)
1517 /* if the stream is paused unpause it, then step */
1519 stream_toggle_pause(is);
1523 static double compute_target_delay(double delay, VideoState *is)
1525 double sync_threshold, diff = 0;
1527 /* update delay to follow master synchronisation source */
1528 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1529 /* if video is slave, we try to correct big delays by
1530 duplicating or deleting a frame */
1531 diff = get_clock(&is->vidclk) - get_master_clock(is);
1533 /* skip or repeat frame. We take into account the
1534 delay to compute the threshold. I still don't know
1535 if it is the best guess */
1536 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1537 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1538 if (diff <= -sync_threshold)
1539 delay = FFMAX(0, delay + diff);
1540 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1541 delay = delay + diff;
1542 else if (diff >= sync_threshold)
1547 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1553 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1554 if (vp->serial == nextvp->serial) {
1555 double duration = nextvp->pts - vp->pts;
1556 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1557 return vp->duration;
1565 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1566 /* update current video pts */
1567 set_clock(&is->vidclk, pts, serial);
1568 sync_clock_to_slave(&is->extclk, &is->vidclk);
1571 /* called to display each frame */
1572 static void video_refresh(void *opaque, double *remaining_time)
1574 VideoState *is = opaque;
1579 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1580 check_external_clock_speed(is);
1582 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1583 time = av_gettime_relative() / 1000000.0;
1584 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1586 is->last_vis_time = time;
1588 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1593 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1594 // nothing to do, no picture to display in the queue
1596 double last_duration, duration, delay;
1599 /* dequeue the picture */
1600 lastvp = frame_queue_peek_last(&is->pictq);
1601 vp = frame_queue_peek(&is->pictq);
1603 if (vp->serial != is->videoq.serial) {
1604 frame_queue_next(&is->pictq);
1608 if (lastvp->serial != vp->serial)
1609 is->frame_timer = av_gettime_relative() / 1000000.0;
1614 /* compute nominal last_duration */
1615 last_duration = vp_duration(is, lastvp, vp);
1616 delay = compute_target_delay(last_duration, is);
1618 time= av_gettime_relative()/1000000.0;
1619 if (time < is->frame_timer + delay) {
1620 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1624 is->frame_timer += delay;
1625 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1626 is->frame_timer = time;
1628 SDL_LockMutex(is->pictq.mutex);
1629 if (!isnan(vp->pts))
1630 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1631 SDL_UnlockMutex(is->pictq.mutex);
1633 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1634 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1635 duration = vp_duration(is, vp, nextvp);
1636 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1637 is->frame_drops_late++;
1638 frame_queue_next(&is->pictq);
1643 if (is->subtitle_st) {
1644 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1645 sp = frame_queue_peek(&is->subpq);
1647 if (frame_queue_nb_remaining(&is->subpq) > 1)
1648 sp2 = frame_queue_peek_next(&is->subpq);
1652 if (sp->serial != is->subtitleq.serial
1653 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1654 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1658 for (i = 0; i < sp->sub.num_rects; i++) {
1659 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1663 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1664 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1665 memset(pixels, 0, sub_rect->w << 2);
1666 SDL_UnlockTexture(is->sub_texture);
1670 frame_queue_next(&is->subpq);
1677 frame_queue_next(&is->pictq);
1678 is->force_refresh = 1;
1680 if (is->step && !is->paused)
1681 stream_toggle_pause(is);
1684 /* display picture */
1685 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1688 is->force_refresh = 0;
1690 static int64_t last_time;
1692 int aqsize, vqsize, sqsize;
1695 cur_time = av_gettime_relative();
1696 if (!last_time || (cur_time - last_time) >= 30000) {
1701 aqsize = is->audioq.size;
1703 vqsize = is->videoq.size;
1704 if (is->subtitle_st)
1705 sqsize = is->subtitleq.size;
1707 if (is->audio_st && is->video_st)
1708 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1709 else if (is->video_st)
1710 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1711 else if (is->audio_st)
1712 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1713 av_log(NULL, AV_LOG_INFO,
1714 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1715 get_master_clock(is),
1716 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1718 is->frame_drops_early + is->frame_drops_late,
1722 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1723 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1725 last_time = cur_time;
1730 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1734 #if defined(DEBUG_SYNC)
1735 printf("frame_type=%c pts=%0.3f\n",
1736 av_get_picture_type_char(src_frame->pict_type), pts);
1739 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1742 vp->sar = src_frame->sample_aspect_ratio;
1745 vp->width = src_frame->width;
1746 vp->height = src_frame->height;
1747 vp->format = src_frame->format;
1750 vp->duration = duration;
1752 vp->serial = serial;
1754 set_default_window_size(vp->width, vp->height, vp->sar);
1756 av_frame_move_ref(vp->frame, src_frame);
1757 frame_queue_push(&is->pictq);
1761 static int get_video_frame(VideoState *is, AVFrame *frame)
1765 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1771 if (frame->pts != AV_NOPTS_VALUE)
1772 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1774 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1776 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1777 if (frame->pts != AV_NOPTS_VALUE) {
1778 double diff = dpts - get_master_clock(is);
1779 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1780 diff - is->frame_last_filter_delay < 0 &&
1781 is->viddec.pkt_serial == is->vidclk.serial &&
1782 is->videoq.nb_packets) {
1783 is->frame_drops_early++;
1784 av_frame_unref(frame);
1795 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1796 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1799 int nb_filters = graph->nb_filters;
1800 AVFilterInOut *outputs = NULL, *inputs = NULL;
1803 outputs = avfilter_inout_alloc();
1804 inputs = avfilter_inout_alloc();
1805 if (!outputs || !inputs) {
1806 ret = AVERROR(ENOMEM);
1810 outputs->name = av_strdup("in");
1811 outputs->filter_ctx = source_ctx;
1812 outputs->pad_idx = 0;
1813 outputs->next = NULL;
1815 inputs->name = av_strdup("out");
1816 inputs->filter_ctx = sink_ctx;
1817 inputs->pad_idx = 0;
1818 inputs->next = NULL;
1820 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1823 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1827 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1828 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1829 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1831 ret = avfilter_graph_config(graph, NULL);
1833 avfilter_inout_free(&outputs);
1834 avfilter_inout_free(&inputs);
1838 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1840 enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
1841 char sws_flags_str[512] = "";
1842 char buffersrc_args[256];
1844 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1845 AVCodecParameters *codecpar = is->video_st->codecpar;
1846 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1847 AVDictionaryEntry *e = NULL;
1848 int nb_pix_fmts = 0;
1851 for (i = 0; i < renderer_info.num_texture_formats; i++) {
1852 for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; j++) {
1853 if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
1854 pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
1859 pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
1861 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1862 if (!strcmp(e->key, "sws_flags")) {
1863 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1865 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1867 if (strlen(sws_flags_str))
1868 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1870 graph->scale_sws_opts = av_strdup(sws_flags_str);
1872 snprintf(buffersrc_args, sizeof(buffersrc_args),
1873 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1874 frame->width, frame->height, frame->format,
1875 is->video_st->time_base.num, is->video_st->time_base.den,
1876 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1877 if (fr.num && fr.den)
1878 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1880 if ((ret = avfilter_graph_create_filter(&filt_src,
1881 avfilter_get_by_name("buffer"),
1882 "ffplay_buffer", buffersrc_args, NULL,
1886 ret = avfilter_graph_create_filter(&filt_out,
1887 avfilter_get_by_name("buffersink"),
1888 "ffplay_buffersink", NULL, NULL, graph);
1892 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1895 last_filter = filt_out;
1897 /* Note: this macro adds a filter before the lastly added filter, so the
1898 * processing order of the filters is in reverse */
1899 #define INSERT_FILT(name, arg) do { \
1900 AVFilterContext *filt_ctx; \
1902 ret = avfilter_graph_create_filter(&filt_ctx, \
1903 avfilter_get_by_name(name), \
1904 "ffplay_" name, arg, NULL, graph); \
1908 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1912 last_filter = filt_ctx; \
1916 double theta = get_rotation(is->video_st);
1918 if (fabs(theta - 90) < 1.0) {
1919 INSERT_FILT("transpose", "clock");
1920 } else if (fabs(theta - 180) < 1.0) {
1921 INSERT_FILT("hflip", NULL);
1922 INSERT_FILT("vflip", NULL);
1923 } else if (fabs(theta - 270) < 1.0) {
1924 INSERT_FILT("transpose", "cclock");
1925 } else if (fabs(theta) > 1.0) {
1926 char rotate_buf[64];
1927 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1928 INSERT_FILT("rotate", rotate_buf);
1932 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1935 is->in_video_filter = filt_src;
1936 is->out_video_filter = filt_out;
1942 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1944 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1945 int sample_rates[2] = { 0, -1 };
1946 int64_t channel_layouts[2] = { 0, -1 };
1947 int channels[2] = { 0, -1 };
1948 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1949 char aresample_swr_opts[512] = "";
1950 AVDictionaryEntry *e = NULL;
1951 char asrc_args[256];
1954 avfilter_graph_free(&is->agraph);
1955 if (!(is->agraph = avfilter_graph_alloc()))
1956 return AVERROR(ENOMEM);
1958 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1959 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1960 if (strlen(aresample_swr_opts))
1961 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1962 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1964 ret = snprintf(asrc_args, sizeof(asrc_args),
1965 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1966 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1967 is->audio_filter_src.channels,
1968 1, is->audio_filter_src.freq);
1969 if (is->audio_filter_src.channel_layout)
1970 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1971 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1973 ret = avfilter_graph_create_filter(&filt_asrc,
1974 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1975 asrc_args, NULL, is->agraph);
1980 ret = avfilter_graph_create_filter(&filt_asink,
1981 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1982 NULL, NULL, is->agraph);
1986 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1988 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1991 if (force_output_format) {
1992 channel_layouts[0] = is->audio_tgt.channel_layout;
1993 channels [0] = is->audio_tgt.channels;
1994 sample_rates [0] = is->audio_tgt.freq;
1995 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1997 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1999 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2001 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2006 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2009 is->in_audio_filter = filt_asrc;
2010 is->out_audio_filter = filt_asink;
2014 avfilter_graph_free(&is->agraph);
2017 #endif /* CONFIG_AVFILTER */
2019 static int audio_thread(void *arg)
2021 VideoState *is = arg;
2022 AVFrame *frame = av_frame_alloc();
2025 int last_serial = -1;
2026 int64_t dec_channel_layout;
2034 return AVERROR(ENOMEM);
2037 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2041 tb = (AVRational){1, frame->sample_rate};
2044 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
2047 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2048 frame->format, frame->channels) ||
2049 is->audio_filter_src.channel_layout != dec_channel_layout ||
2050 is->audio_filter_src.freq != frame->sample_rate ||
2051 is->auddec.pkt_serial != last_serial;
2054 char buf1[1024], buf2[1024];
2055 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2056 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2057 av_log(NULL, AV_LOG_DEBUG,
2058 "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",
2059 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2060 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2062 is->audio_filter_src.fmt = frame->format;
2063 is->audio_filter_src.channels = frame->channels;
2064 is->audio_filter_src.channel_layout = dec_channel_layout;
2065 is->audio_filter_src.freq = frame->sample_rate;
2066 last_serial = is->auddec.pkt_serial;
2068 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2072 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2075 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2076 tb = av_buffersink_get_time_base(is->out_audio_filter);
2078 if (!(af = frame_queue_peek_writable(&is->sampq)))
2081 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2082 af->pos = frame->pkt_pos;
2083 af->serial = is->auddec.pkt_serial;
2084 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2086 av_frame_move_ref(af->frame, frame);
2087 frame_queue_push(&is->sampq);
2090 if (is->audioq.serial != is->auddec.pkt_serial)
2093 if (ret == AVERROR_EOF)
2094 is->auddec.finished = is->auddec.pkt_serial;
2097 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2100 avfilter_graph_free(&is->agraph);
2102 av_frame_free(&frame);
2106 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2108 packet_queue_start(d->queue);
2109 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2110 if (!d->decoder_tid) {
2111 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2112 return AVERROR(ENOMEM);
2117 static int video_thread(void *arg)
2119 VideoState *is = arg;
2120 AVFrame *frame = av_frame_alloc();
2124 AVRational tb = is->video_st->time_base;
2125 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2128 AVFilterGraph *graph = avfilter_graph_alloc();
2129 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2132 enum AVPixelFormat last_format = -2;
2133 int last_serial = -1;
2134 int last_vfilter_idx = 0;
2136 av_frame_free(&frame);
2137 return AVERROR(ENOMEM);
2144 avfilter_graph_free(&graph);
2146 return AVERROR(ENOMEM);
2150 ret = get_video_frame(is, frame);
2157 if ( last_w != frame->width
2158 || last_h != frame->height
2159 || last_format != frame->format
2160 || last_serial != is->viddec.pkt_serial
2161 || last_vfilter_idx != is->vfilter_idx) {
2162 av_log(NULL, AV_LOG_DEBUG,
2163 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2165 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2166 frame->width, frame->height,
2167 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2168 avfilter_graph_free(&graph);
2169 graph = avfilter_graph_alloc();
2170 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2172 event.type = FF_QUIT_EVENT;
2173 event.user.data1 = is;
2174 SDL_PushEvent(&event);
2177 filt_in = is->in_video_filter;
2178 filt_out = is->out_video_filter;
2179 last_w = frame->width;
2180 last_h = frame->height;
2181 last_format = frame->format;
2182 last_serial = is->viddec.pkt_serial;
2183 last_vfilter_idx = is->vfilter_idx;
2184 frame_rate = av_buffersink_get_frame_rate(filt_out);
2187 ret = av_buffersrc_add_frame(filt_in, frame);
2192 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2194 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2196 if (ret == AVERROR_EOF)
2197 is->viddec.finished = is->viddec.pkt_serial;
2202 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2203 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2204 is->frame_last_filter_delay = 0;
2205 tb = av_buffersink_get_time_base(filt_out);
2207 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2208 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2209 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2210 av_frame_unref(frame);
2212 if (is->videoq.serial != is->viddec.pkt_serial)
2222 avfilter_graph_free(&graph);
2224 av_frame_free(&frame);
2228 static int subtitle_thread(void *arg)
2230 VideoState *is = arg;
2236 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2239 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2244 if (got_subtitle && sp->sub.format == 0) {
2245 if (sp->sub.pts != AV_NOPTS_VALUE)
2246 pts = sp->sub.pts / (double)AV_TIME_BASE;
2248 sp->serial = is->subdec.pkt_serial;
2249 sp->width = is->subdec.avctx->width;
2250 sp->height = is->subdec.avctx->height;
2253 /* now we can update the picture count */
2254 frame_queue_push(&is->subpq);
2255 } else if (got_subtitle) {
2256 avsubtitle_free(&sp->sub);
2262 /* copy samples for viewing in editor window */
2263 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2267 size = samples_size / sizeof(short);
2269 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2272 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2274 is->sample_array_index += len;
2275 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2276 is->sample_array_index = 0;
2281 /* return the wanted number of samples to get better sync if sync_type is video
2282 * or external master clock */
2283 static int synchronize_audio(VideoState *is, int nb_samples)
2285 int wanted_nb_samples = nb_samples;
2287 /* if not master, then we try to remove or add samples to correct the clock */
2288 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2289 double diff, avg_diff;
2290 int min_nb_samples, max_nb_samples;
2292 diff = get_clock(&is->audclk) - get_master_clock(is);
2294 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2295 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2296 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2297 /* not enough measures to have a correct estimate */
2298 is->audio_diff_avg_count++;
2300 /* estimate the A-V difference */
2301 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2303 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2304 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2305 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2306 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2307 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2309 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2310 diff, avg_diff, wanted_nb_samples - nb_samples,
2311 is->audio_clock, is->audio_diff_threshold);
2314 /* too big difference : may be initial PTS errors, so
2316 is->audio_diff_avg_count = 0;
2317 is->audio_diff_cum = 0;
2321 return wanted_nb_samples;
2325 * Decode one audio frame and return its uncompressed size.
2327 * The processed audio frame is decoded, converted if required, and
2328 * stored in is->audio_buf, with size in bytes given by the return
2331 static int audio_decode_frame(VideoState *is)
2333 int data_size, resampled_data_size;
2334 int64_t dec_channel_layout;
2335 av_unused double audio_clock0;
2336 int wanted_nb_samples;
2344 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2345 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2350 if (!(af = frame_queue_peek_readable(&is->sampq)))
2352 frame_queue_next(&is->sampq);
2353 } while (af->serial != is->audioq.serial);
2355 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2356 af->frame->nb_samples,
2357 af->frame->format, 1);
2359 dec_channel_layout =
2360 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2361 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2362 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2364 if (af->frame->format != is->audio_src.fmt ||
2365 dec_channel_layout != is->audio_src.channel_layout ||
2366 af->frame->sample_rate != is->audio_src.freq ||
2367 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2368 swr_free(&is->swr_ctx);
2369 is->swr_ctx = swr_alloc_set_opts(NULL,
2370 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2371 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2373 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2374 av_log(NULL, AV_LOG_ERROR,
2375 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2376 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2377 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2378 swr_free(&is->swr_ctx);
2381 is->audio_src.channel_layout = dec_channel_layout;
2382 is->audio_src.channels = af->frame->channels;
2383 is->audio_src.freq = af->frame->sample_rate;
2384 is->audio_src.fmt = af->frame->format;
2388 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2389 uint8_t **out = &is->audio_buf1;
2390 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2391 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2394 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2397 if (wanted_nb_samples != af->frame->nb_samples) {
2398 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2399 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2400 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2404 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2405 if (!is->audio_buf1)
2406 return AVERROR(ENOMEM);
2407 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2409 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2412 if (len2 == out_count) {
2413 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2414 if (swr_init(is->swr_ctx) < 0)
2415 swr_free(&is->swr_ctx);
2417 is->audio_buf = is->audio_buf1;
2418 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2420 is->audio_buf = af->frame->data[0];
2421 resampled_data_size = data_size;
2424 audio_clock0 = is->audio_clock;
2425 /* update the audio clock with the pts */
2426 if (!isnan(af->pts))
2427 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2429 is->audio_clock = NAN;
2430 is->audio_clock_serial = af->serial;
2433 static double last_clock;
2434 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2435 is->audio_clock - last_clock,
2436 is->audio_clock, audio_clock0);
2437 last_clock = is->audio_clock;
2440 return resampled_data_size;
2443 /* prepare a new audio buffer */
2444 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2446 VideoState *is = opaque;
2447 int audio_size, len1;
2449 audio_callback_time = av_gettime_relative();
2452 if (is->audio_buf_index >= is->audio_buf_size) {
2453 audio_size = audio_decode_frame(is);
2454 if (audio_size < 0) {
2455 /* if error, just output silence */
2456 is->audio_buf = NULL;
2457 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2459 if (is->show_mode != SHOW_MODE_VIDEO)
2460 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2461 is->audio_buf_size = audio_size;
2463 is->audio_buf_index = 0;
2465 len1 = is->audio_buf_size - is->audio_buf_index;
2468 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2469 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2471 memset(stream, 0, len1);
2472 if (!is->muted && is->audio_buf)
2473 SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
2477 is->audio_buf_index += len1;
2479 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2480 /* Let's assume the audio driver that is used by SDL has two periods. */
2481 if (!isnan(is->audio_clock)) {
2482 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);
2483 sync_clock_to_slave(&is->extclk, &is->audclk);
2487 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2489 SDL_AudioSpec wanted_spec, spec;
2491 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2492 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2493 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2495 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2497 wanted_nb_channels = atoi(env);
2498 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2500 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2501 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2502 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2504 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2505 wanted_spec.channels = wanted_nb_channels;
2506 wanted_spec.freq = wanted_sample_rate;
2507 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2508 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2511 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2512 next_sample_rate_idx--;
2513 wanted_spec.format = AUDIO_S16SYS;
2514 wanted_spec.silence = 0;
2515 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2516 wanted_spec.callback = sdl_audio_callback;
2517 wanted_spec.userdata = opaque;
2518 while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
2519 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2520 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2521 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2522 if (!wanted_spec.channels) {
2523 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2524 wanted_spec.channels = wanted_nb_channels;
2525 if (!wanted_spec.freq) {
2526 av_log(NULL, AV_LOG_ERROR,
2527 "No more combinations to try, audio open failed\n");
2531 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2533 if (spec.format != AUDIO_S16SYS) {
2534 av_log(NULL, AV_LOG_ERROR,
2535 "SDL advised audio format %d is not supported!\n", spec.format);
2538 if (spec.channels != wanted_spec.channels) {
2539 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2540 if (!wanted_channel_layout) {
2541 av_log(NULL, AV_LOG_ERROR,
2542 "SDL advised channel count %d is not supported!\n", spec.channels);
2547 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2548 audio_hw_params->freq = spec.freq;
2549 audio_hw_params->channel_layout = wanted_channel_layout;
2550 audio_hw_params->channels = spec.channels;
2551 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2552 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);
2553 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2554 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2560 /* open a given stream. Return 0 if OK */
2561 static int stream_component_open(VideoState *is, int stream_index)
2563 AVFormatContext *ic = is->ic;
2564 AVCodecContext *avctx;
2566 const char *forced_codec_name = NULL;
2567 AVDictionary *opts = NULL;
2568 AVDictionaryEntry *t = NULL;
2569 int sample_rate, nb_channels;
2570 int64_t channel_layout;
2572 int stream_lowres = lowres;
2574 if (stream_index < 0 || stream_index >= ic->nb_streams)
2577 avctx = avcodec_alloc_context3(NULL);
2579 return AVERROR(ENOMEM);
2581 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2584 avctx->pkt_timebase = ic->streams[stream_index]->time_base;
2586 codec = avcodec_find_decoder(avctx->codec_id);
2588 switch(avctx->codec_type){
2589 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2590 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2591 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2593 if (forced_codec_name)
2594 codec = avcodec_find_decoder_by_name(forced_codec_name);
2596 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2597 "No codec could be found with name '%s'\n", forced_codec_name);
2598 else av_log(NULL, AV_LOG_WARNING,
2599 "No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
2600 ret = AVERROR(EINVAL);
2604 avctx->codec_id = codec->id;
2605 if (stream_lowres > codec->max_lowres) {
2606 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2608 stream_lowres = codec->max_lowres;
2610 avctx->lowres = stream_lowres;
2613 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2615 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2616 if (!av_dict_get(opts, "threads", NULL, 0))
2617 av_dict_set(&opts, "threads", "auto", 0);
2619 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2620 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2621 av_dict_set(&opts, "refcounted_frames", "1", 0);
2622 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2625 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2626 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2627 ret = AVERROR_OPTION_NOT_FOUND;
2632 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2633 switch (avctx->codec_type) {
2634 case AVMEDIA_TYPE_AUDIO:
2637 AVFilterContext *sink;
2639 is->audio_filter_src.freq = avctx->sample_rate;
2640 is->audio_filter_src.channels = avctx->channels;
2641 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2642 is->audio_filter_src.fmt = avctx->sample_fmt;
2643 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2645 sink = is->out_audio_filter;
2646 sample_rate = av_buffersink_get_sample_rate(sink);
2647 nb_channels = av_buffersink_get_channels(sink);
2648 channel_layout = av_buffersink_get_channel_layout(sink);
2651 sample_rate = avctx->sample_rate;
2652 nb_channels = avctx->channels;
2653 channel_layout = avctx->channel_layout;
2656 /* prepare audio output */
2657 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2659 is->audio_hw_buf_size = ret;
2660 is->audio_src = is->audio_tgt;
2661 is->audio_buf_size = 0;
2662 is->audio_buf_index = 0;
2664 /* init averaging filter */
2665 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2666 is->audio_diff_avg_count = 0;
2667 /* since we do not have a precise anough audio FIFO fullness,
2668 we correct audio sync only if larger than this threshold */
2669 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2671 is->audio_stream = stream_index;
2672 is->audio_st = ic->streams[stream_index];
2674 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2675 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2676 is->auddec.start_pts = is->audio_st->start_time;
2677 is->auddec.start_pts_tb = is->audio_st->time_base;
2679 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2681 SDL_PauseAudioDevice(audio_dev, 0);
2683 case AVMEDIA_TYPE_VIDEO:
2684 is->video_stream = stream_index;
2685 is->video_st = ic->streams[stream_index];
2687 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2688 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2690 is->queue_attachments_req = 1;
2692 case AVMEDIA_TYPE_SUBTITLE:
2693 is->subtitle_stream = stream_index;
2694 is->subtitle_st = ic->streams[stream_index];
2696 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2697 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2706 avcodec_free_context(&avctx);
2708 av_dict_free(&opts);
2713 static int decode_interrupt_cb(void *ctx)
2715 VideoState *is = ctx;
2716 return is->abort_request;
2719 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2720 return stream_id < 0 ||
2721 queue->abort_request ||
2722 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2723 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2726 static int is_realtime(AVFormatContext *s)
2728 if( !strcmp(s->iformat->name, "rtp")
2729 || !strcmp(s->iformat->name, "rtsp")
2730 || !strcmp(s->iformat->name, "sdp")
2734 if(s->pb && ( !strncmp(s->url, "rtp:", 4)
2735 || !strncmp(s->url, "udp:", 4)
2742 /* this thread gets the stream from the disk or the network */
2743 static int read_thread(void *arg)
2745 VideoState *is = arg;
2746 AVFormatContext *ic = NULL;
2748 int st_index[AVMEDIA_TYPE_NB];
2749 AVPacket pkt1, *pkt = &pkt1;
2750 int64_t stream_start_time;
2751 int pkt_in_play_range = 0;
2752 AVDictionaryEntry *t;
2753 SDL_mutex *wait_mutex = SDL_CreateMutex();
2754 int scan_all_pmts_set = 0;
2758 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2759 ret = AVERROR(ENOMEM);
2763 memset(st_index, -1, sizeof(st_index));
2764 is->last_video_stream = is->video_stream = -1;
2765 is->last_audio_stream = is->audio_stream = -1;
2766 is->last_subtitle_stream = is->subtitle_stream = -1;
2769 ic = avformat_alloc_context();
2771 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2772 ret = AVERROR(ENOMEM);
2775 ic->interrupt_callback.callback = decode_interrupt_cb;
2776 ic->interrupt_callback.opaque = is;
2777 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2778 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2779 scan_all_pmts_set = 1;
2781 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2783 print_error(is->filename, err);
2787 if (scan_all_pmts_set)
2788 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2790 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2791 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2792 ret = AVERROR_OPTION_NOT_FOUND;
2798 ic->flags |= AVFMT_FLAG_GENPTS;
2800 av_format_inject_global_side_data(ic);
2802 if (find_stream_info) {
2803 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2804 int orig_nb_streams = ic->nb_streams;
2806 err = avformat_find_stream_info(ic, opts);
2808 for (i = 0; i < orig_nb_streams; i++)
2809 av_dict_free(&opts[i]);
2813 av_log(NULL, AV_LOG_WARNING,
2814 "%s: could not find codec parameters\n", is->filename);
2821 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2823 if (seek_by_bytes < 0)
2824 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2826 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2828 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2829 window_title = av_asprintf("%s - %s", t->value, input_filename);
2831 /* if seeking requested, we execute it */
2832 if (start_time != AV_NOPTS_VALUE) {
2835 timestamp = start_time;
2836 /* add the stream start time */
2837 if (ic->start_time != AV_NOPTS_VALUE)
2838 timestamp += ic->start_time;
2839 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2841 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2842 is->filename, (double)timestamp / AV_TIME_BASE);
2846 is->realtime = is_realtime(ic);
2849 av_dump_format(ic, 0, is->filename, 0);
2851 for (i = 0; i < ic->nb_streams; i++) {
2852 AVStream *st = ic->streams[i];
2853 enum AVMediaType type = st->codecpar->codec_type;
2854 st->discard = AVDISCARD_ALL;
2855 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2856 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2859 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2860 if (wanted_stream_spec[i] && st_index[i] == -1) {
2861 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));
2862 st_index[i] = INT_MAX;
2867 st_index[AVMEDIA_TYPE_VIDEO] =
2868 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2869 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2871 st_index[AVMEDIA_TYPE_AUDIO] =
2872 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2873 st_index[AVMEDIA_TYPE_AUDIO],
2874 st_index[AVMEDIA_TYPE_VIDEO],
2876 if (!video_disable && !subtitle_disable)
2877 st_index[AVMEDIA_TYPE_SUBTITLE] =
2878 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2879 st_index[AVMEDIA_TYPE_SUBTITLE],
2880 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2881 st_index[AVMEDIA_TYPE_AUDIO] :
2882 st_index[AVMEDIA_TYPE_VIDEO]),
2885 is->show_mode = show_mode;
2886 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2887 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2888 AVCodecParameters *codecpar = st->codecpar;
2889 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2890 if (codecpar->width)
2891 set_default_window_size(codecpar->width, codecpar->height, sar);
2894 /* open the streams */
2895 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2896 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2900 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2901 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2903 if (is->show_mode == SHOW_MODE_NONE)
2904 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2906 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2907 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2910 if (is->video_stream < 0 && is->audio_stream < 0) {
2911 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2917 if (infinite_buffer < 0 && is->realtime)
2918 infinite_buffer = 1;
2921 if (is->abort_request)
2923 if (is->paused != is->last_paused) {
2924 is->last_paused = is->paused;
2926 is->read_pause_return = av_read_pause(ic);
2930 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2932 (!strcmp(ic->iformat->name, "rtsp") ||
2933 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2934 /* wait 10 ms to avoid trying to get another packet */
2941 int64_t seek_target = is->seek_pos;
2942 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2943 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2944 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2945 // of the seek_pos/seek_rel variables
2947 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2949 av_log(NULL, AV_LOG_ERROR,
2950 "%s: error while seeking\n", is->ic->url);
2952 if (is->audio_stream >= 0) {
2953 packet_queue_flush(&is->audioq);
2954 packet_queue_put(&is->audioq, &flush_pkt);
2956 if (is->subtitle_stream >= 0) {
2957 packet_queue_flush(&is->subtitleq);
2958 packet_queue_put(&is->subtitleq, &flush_pkt);
2960 if (is->video_stream >= 0) {
2961 packet_queue_flush(&is->videoq);
2962 packet_queue_put(&is->videoq, &flush_pkt);
2964 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2965 set_clock(&is->extclk, NAN, 0);
2967 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2971 is->queue_attachments_req = 1;
2974 step_to_next_frame(is);
2976 if (is->queue_attachments_req) {
2977 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2978 AVPacket copy = { 0 };
2979 if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0)
2981 packet_queue_put(&is->videoq, ©);
2982 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2984 is->queue_attachments_req = 0;
2987 /* if the queue are full, no need to read more */
2988 if (infinite_buffer<1 &&
2989 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2990 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2991 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2992 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2994 SDL_LockMutex(wait_mutex);
2995 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2996 SDL_UnlockMutex(wait_mutex);
3000 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3001 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3002 if (loop != 1 && (!loop || --loop)) {
3003 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3004 } else if (autoexit) {
3009 ret = av_read_frame(ic, pkt);
3011 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3012 if (is->video_stream >= 0)
3013 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3014 if (is->audio_stream >= 0)
3015 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3016 if (is->subtitle_stream >= 0)
3017 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3020 if (ic->pb && ic->pb->error)
3022 SDL_LockMutex(wait_mutex);
3023 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3024 SDL_UnlockMutex(wait_mutex);
3029 /* check if packet is in play range specified by user, then queue, otherwise discard */
3030 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3031 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3032 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3033 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3034 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3035 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3036 <= ((double)duration / 1000000);
3037 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3038 packet_queue_put(&is->audioq, pkt);
3039 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3040 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3041 packet_queue_put(&is->videoq, pkt);
3042 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3043 packet_queue_put(&is->subtitleq, pkt);
3045 av_packet_unref(pkt);
3052 avformat_close_input(&ic);
3057 event.type = FF_QUIT_EVENT;
3058 event.user.data1 = is;
3059 SDL_PushEvent(&event);
3061 SDL_DestroyMutex(wait_mutex);
3065 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3069 is = av_mallocz(sizeof(VideoState));
3072 is->filename = av_strdup(filename);
3075 is->iformat = iformat;
3079 /* start video display */
3080 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3082 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3084 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3087 if (packet_queue_init(&is->videoq) < 0 ||
3088 packet_queue_init(&is->audioq) < 0 ||
3089 packet_queue_init(&is->subtitleq) < 0)
3092 if (!(is->continue_read_thread = SDL_CreateCond())) {
3093 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3097 init_clock(&is->vidclk, &is->videoq.serial);
3098 init_clock(&is->audclk, &is->audioq.serial);
3099 init_clock(&is->extclk, &is->extclk.serial);
3100 is->audio_clock_serial = -1;
3101 if (startup_volume < 0)
3102 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3103 if (startup_volume > 100)
3104 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3105 startup_volume = av_clip(startup_volume, 0, 100);
3106 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3107 is->audio_volume = startup_volume;
3109 is->av_sync_type = av_sync_type;
3110 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3111 if (!is->read_tid) {
3112 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3120 static void stream_cycle_channel(VideoState *is, int codec_type)
3122 AVFormatContext *ic = is->ic;
3123 int start_index, stream_index;
3126 AVProgram *p = NULL;
3127 int nb_streams = is->ic->nb_streams;
3129 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3130 start_index = is->last_video_stream;
3131 old_index = is->video_stream;
3132 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3133 start_index = is->last_audio_stream;
3134 old_index = is->audio_stream;
3136 start_index = is->last_subtitle_stream;
3137 old_index = is->subtitle_stream;
3139 stream_index = start_index;
3141 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3142 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3144 nb_streams = p->nb_stream_indexes;
3145 for (start_index = 0; start_index < nb_streams; start_index++)
3146 if (p->stream_index[start_index] == stream_index)
3148 if (start_index == nb_streams)
3150 stream_index = start_index;
3155 if (++stream_index >= nb_streams)
3157 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3160 is->last_subtitle_stream = -1;
3163 if (start_index == -1)
3167 if (stream_index == start_index)
3169 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3170 if (st->codecpar->codec_type == codec_type) {
3171 /* check that parameters are OK */
3172 switch (codec_type) {
3173 case AVMEDIA_TYPE_AUDIO:
3174 if (st->codecpar->sample_rate != 0 &&
3175 st->codecpar->channels != 0)
3178 case AVMEDIA_TYPE_VIDEO:
3179 case AVMEDIA_TYPE_SUBTITLE:
3187 if (p && stream_index != -1)
3188 stream_index = p->stream_index[stream_index];
3189 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3190 av_get_media_type_string(codec_type),
3194 stream_component_close(is, old_index);
3195 stream_component_open(is, stream_index);
3199 static void toggle_full_screen(VideoState *is)
3201 is_full_screen = !is_full_screen;
3202 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3205 static void toggle_audio_display(VideoState *is)
3207 int next = is->show_mode;
3209 next = (next + 1) % SHOW_MODE_NB;
3210 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3211 if (is->show_mode != next) {
3212 is->force_refresh = 1;
3213 is->show_mode = next;
3217 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3218 double remaining_time = 0.0;
3220 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3221 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3225 if (remaining_time > 0.0)
3226 av_usleep((int64_t)(remaining_time * 1000000.0));
3227 remaining_time = REFRESH_RATE;
3228 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3229 video_refresh(is, &remaining_time);
3234 static void seek_chapter(VideoState *is, int incr)
3236 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3239 if (!is->ic->nb_chapters)
3242 /* find the current chapter */
3243 for (i = 0; i < is->ic->nb_chapters; i++) {
3244 AVChapter *ch = is->ic->chapters[i];
3245 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3253 if (i >= is->ic->nb_chapters)
3256 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3257 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3258 AV_TIME_BASE_Q), 0, 0);
3261 /* handle an event sent by the GUI */
3262 static void event_loop(VideoState *cur_stream)
3265 double incr, pos, frac;
3269 refresh_loop_wait_event(cur_stream, &event);
3270 switch (event.type) {
3272 if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
3273 do_exit(cur_stream);
3276 // If we don't yet have a window, skip all key events, because read_thread might still be initializing...
3277 if (!cur_stream->width)
3279 switch (event.key.keysym.sym) {
3281 toggle_full_screen(cur_stream);
3282 cur_stream->force_refresh = 1;
3286 toggle_pause(cur_stream);
3289 toggle_mute(cur_stream);
3291 case SDLK_KP_MULTIPLY:
3293 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3295 case SDLK_KP_DIVIDE:
3297 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3299 case SDLK_s: // S: Step to next frame
3300 step_to_next_frame(cur_stream);
3303 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3306 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3309 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3310 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3311 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3314 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3318 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3319 if (++cur_stream->vfilter_idx >= nb_vfilters)
3320 cur_stream->vfilter_idx = 0;
3322 cur_stream->vfilter_idx = 0;
3323 toggle_audio_display(cur_stream);
3326 toggle_audio_display(cur_stream);
3330 if (cur_stream->ic->nb_chapters <= 1) {
3334 seek_chapter(cur_stream, 1);
3337 if (cur_stream->ic->nb_chapters <= 1) {
3341 seek_chapter(cur_stream, -1);
3344 incr = seek_interval ? -seek_interval : -10.0;
3347 incr = seek_interval ? seek_interval : 10.0;
3355 if (seek_by_bytes) {
3357 if (pos < 0 && cur_stream->video_stream >= 0)
3358 pos = frame_queue_last_pos(&cur_stream->pictq);
3359 if (pos < 0 && cur_stream->audio_stream >= 0)
3360 pos = frame_queue_last_pos(&cur_stream->sampq);
3362 pos = avio_tell(cur_stream->ic->pb);
3363 if (cur_stream->ic->bit_rate)
3364 incr *= cur_stream->ic->bit_rate / 8.0;
3368 stream_seek(cur_stream, pos, incr, 1);
3370 pos = get_master_clock(cur_stream);
3372 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3374 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3375 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3376 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3383 case SDL_MOUSEBUTTONDOWN:
3384 if (exit_on_mousedown) {
3385 do_exit(cur_stream);
3388 if (event.button.button == SDL_BUTTON_LEFT) {
3389 static int64_t last_mouse_left_click = 0;
3390 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3391 toggle_full_screen(cur_stream);
3392 cur_stream->force_refresh = 1;
3393 last_mouse_left_click = 0;
3395 last_mouse_left_click = av_gettime_relative();
3398 case SDL_MOUSEMOTION:
3399 if (cursor_hidden) {
3403 cursor_last_shown = av_gettime_relative();
3404 if (event.type == SDL_MOUSEBUTTONDOWN) {
3405 if (event.button.button != SDL_BUTTON_RIGHT)
3409 if (!(event.motion.state & SDL_BUTTON_RMASK))
3413 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3414 uint64_t size = avio_size(cur_stream->ic->pb);
3415 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3419 int tns, thh, tmm, tss;
3420 tns = cur_stream->ic->duration / 1000000LL;
3422 tmm = (tns % 3600) / 60;
3424 frac = x / cur_stream->width;
3427 mm = (ns % 3600) / 60;
3429 av_log(NULL, AV_LOG_INFO,
3430 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3431 hh, mm, ss, thh, tmm, tss);
3432 ts = frac * cur_stream->ic->duration;
3433 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3434 ts += cur_stream->ic->start_time;
3435 stream_seek(cur_stream, ts, 0, 0);
3438 case SDL_WINDOWEVENT:
3439 switch (event.window.event) {
3440 case SDL_WINDOWEVENT_RESIZED:
3441 screen_width = cur_stream->width = event.window.data1;
3442 screen_height = cur_stream->height = event.window.data2;
3443 if (cur_stream->vis_texture) {
3444 SDL_DestroyTexture(cur_stream->vis_texture);
3445 cur_stream->vis_texture = NULL;
3447 case SDL_WINDOWEVENT_EXPOSED:
3448 cur_stream->force_refresh = 1;
3453 do_exit(cur_stream);
3461 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3463 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3464 return opt_default(NULL, "video_size", arg);
3467 static int opt_width(void *optctx, const char *opt, const char *arg)
3469 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3473 static int opt_height(void *optctx, const char *opt, const char *arg)
3475 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3479 static int opt_format(void *optctx, const char *opt, const char *arg)
3481 file_iformat = av_find_input_format(arg);
3482 if (!file_iformat) {
3483 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3484 return AVERROR(EINVAL);
3489 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3491 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3492 return opt_default(NULL, "pixel_format", arg);
3495 static int opt_sync(void *optctx, const char *opt, const char *arg)
3497 if (!strcmp(arg, "audio"))
3498 av_sync_type = AV_SYNC_AUDIO_MASTER;
3499 else if (!strcmp(arg, "video"))
3500 av_sync_type = AV_SYNC_VIDEO_MASTER;
3501 else if (!strcmp(arg, "ext"))
3502 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3504 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3510 static int opt_seek(void *optctx, const char *opt, const char *arg)
3512 start_time = parse_time_or_die(opt, arg, 1);
3516 static int opt_duration(void *optctx, const char *opt, const char *arg)
3518 duration = parse_time_or_die(opt, arg, 1);
3522 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3524 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3525 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3526 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3527 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3531 static void opt_input_file(void *optctx, const char *filename)
3533 if (input_filename) {
3534 av_log(NULL, AV_LOG_FATAL,
3535 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3536 filename, input_filename);
3539 if (!strcmp(filename, "-"))
3541 input_filename = filename;
3544 static int opt_codec(void *optctx, const char *opt, const char *arg)
3546 const char *spec = strchr(opt, ':');
3548 av_log(NULL, AV_LOG_ERROR,
3549 "No media specifier was specified in '%s' in option '%s'\n",
3551 return AVERROR(EINVAL);
3555 case 'a' : audio_codec_name = arg; break;
3556 case 's' : subtitle_codec_name = arg; break;
3557 case 'v' : video_codec_name = arg; break;
3559 av_log(NULL, AV_LOG_ERROR,
3560 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3561 return AVERROR(EINVAL);
3568 static const OptionDef options[] = {
3569 CMDUTILS_COMMON_OPTIONS
3570 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3571 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3572 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3573 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3574 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3575 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3576 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3577 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3578 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3579 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3580 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3581 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3582 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3583 { "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
3584 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3585 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3586 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3587 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3588 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3589 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3590 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3591 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3592 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3593 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3594 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3595 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3596 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3597 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3598 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3599 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3600 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3601 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3602 { "left", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_left }, "set the x position for the left of the window", "x pos" },
3603 { "top", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_top }, "set the y position for the top of the window", "y pos" },
3605 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3606 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3608 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3609 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3610 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3611 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3612 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3613 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3614 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3615 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3616 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3617 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3618 "read and decode the streams to fill missing information with heuristics" },
3622 static void show_usage(void)
3624 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3625 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3626 av_log(NULL, AV_LOG_INFO, "\n");
3629 void show_help_default(const char *opt, const char *arg)
3631 av_log_set_callback(log_callback_help);
3633 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3634 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3636 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3637 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3638 #if !CONFIG_AVFILTER
3639 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3641 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3643 printf("\nWhile playing:\n"
3645 "f toggle full screen\n"
3648 "9, 0 decrease and increase volume respectively\n"
3649 "/, * decrease and increase volume respectively\n"
3650 "a cycle audio channel in the current program\n"
3651 "v cycle video channel\n"
3652 "t cycle subtitle channel in the current program\n"
3654 "w cycle video filters or show modes\n"
3655 "s activate frame-step mode\n"
3656 "left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
3657 "down/up seek backward/forward 1 minute\n"
3658 "page down/page up seek backward/forward 10 minutes\n"
3659 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3660 "left double-click toggle full screen\n"
3664 /* Called from the main */
3665 int main(int argc, char **argv)
3672 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3673 parse_loglevel(argc, argv, options);
3675 /* register all codecs, demux and protocols */
3677 avdevice_register_all();
3679 avformat_network_init();
3683 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3684 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3686 show_banner(argc, argv, options);
3688 parse_options(NULL, argc, argv, options, opt_input_file);
3690 if (!input_filename) {
3692 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3693 av_log(NULL, AV_LOG_FATAL,
3694 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3698 if (display_disable) {
3701 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3703 flags &= ~SDL_INIT_AUDIO;
3705 /* Try to work around an occasional ALSA buffer underflow issue when the
3706 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3707 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3708 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3710 if (display_disable)
3711 flags &= ~SDL_INIT_VIDEO;
3712 if (SDL_Init (flags)) {
3713 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3714 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3718 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3719 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3721 av_init_packet(&flush_pkt);
3722 flush_pkt.data = (uint8_t *)&flush_pkt;
3724 if (!display_disable) {
3725 int flags = SDL_WINDOW_HIDDEN;
3727 flags |= SDL_WINDOW_BORDERLESS;
3729 flags |= SDL_WINDOW_RESIZABLE;
3730 window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
3731 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
3733 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
3735 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
3736 renderer = SDL_CreateRenderer(window, -1, 0);
3739 if (!SDL_GetRendererInfo(renderer, &renderer_info))
3740 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
3743 if (!window || !renderer || !renderer_info.num_texture_formats) {
3744 av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
3749 is = stream_open(input_filename, file_iformat);
3751 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");