2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control in dB */
77 #define SDL_VOLUME_STEP (0.75)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
110 static unsigned sws_flags = SWS_BICUBIC;
112 typedef struct MyAVPacketList {
114 struct MyAVPacketList *next;
118 typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
134 typedef struct AudioParams {
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
143 typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
148 int serial; /* clock is based on a packet with this serial */
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
169 typedef struct FrameQueue {
170 Frame queue[FRAME_QUEUE_SIZE];
183 AV_SYNC_AUDIO_MASTER, /* default choice */
184 AV_SYNC_VIDEO_MASTER,
185 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
188 typedef struct Decoder {
191 AVCodecContext *avctx;
195 SDL_cond *empty_queue_cond;
197 AVRational start_pts_tb;
199 AVRational next_pts_tb;
200 SDL_Thread *decoder_tid;
203 typedef struct VideoState {
204 SDL_Thread *read_tid;
205 AVInputFormat *iformat;
210 int queue_attachments_req;
215 int read_pause_return;
236 int audio_clock_serial;
237 double audio_diff_cum; /* used for AV difference average computation */
238 double audio_diff_avg_coef;
239 double audio_diff_threshold;
240 int audio_diff_avg_count;
243 int audio_hw_buf_size;
246 unsigned int audio_buf_size; /* in bytes */
247 unsigned int audio_buf1_size;
248 int audio_buf_index; /* in bytes */
249 int audio_write_buf_size;
252 struct AudioParams audio_src;
254 struct AudioParams audio_filter_src;
256 struct AudioParams audio_tgt;
257 struct SwrContext *swr_ctx;
258 int frame_drops_early;
259 int frame_drops_late;
262 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
264 int16_t sample_array[SAMPLE_ARRAY_SIZE];
265 int sample_array_index;
269 FFTSample *rdft_data;
271 double last_vis_time;
272 SDL_Texture *vis_texture;
273 SDL_Texture *sub_texture;
274 SDL_Texture *vid_texture;
277 AVStream *subtitle_st;
278 PacketQueue subtitleq;
281 double frame_last_returned_time;
282 double frame_last_filter_delay;
286 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
287 struct SwsContext *img_convert_ctx;
288 struct SwsContext *sub_convert_ctx;
292 int width, height, xleft, ytop;
297 AVFilterContext *in_video_filter; // the first filter in the video chain
298 AVFilterContext *out_video_filter; // the last filter in the video chain
299 AVFilterContext *in_audio_filter; // the first filter in the audio chain
300 AVFilterContext *out_audio_filter; // the last filter in the audio chain
301 AVFilterGraph *agraph; // audio filter graph
304 int last_video_stream, last_audio_stream, last_subtitle_stream;
306 SDL_cond *continue_read_thread;
309 /* options specified by the user */
310 static AVInputFormat *file_iformat;
311 static const char *input_filename;
312 static const char *window_title;
313 static int default_width = 640;
314 static int default_height = 480;
315 static int screen_width = 0;
316 static int screen_height = 0;
317 static int audio_disable;
318 static int video_disable;
319 static int subtitle_disable;
320 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
321 static int seek_by_bytes = -1;
322 static int display_disable;
323 static int borderless;
324 static int startup_volume = 100;
325 static int show_status = 1;
326 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
327 static int64_t start_time = AV_NOPTS_VALUE;
328 static int64_t duration = AV_NOPTS_VALUE;
330 static int genpts = 0;
331 static int lowres = 0;
332 static int decoder_reorder_pts = -1;
334 static int exit_on_keydown;
335 static int exit_on_mousedown;
337 static int framedrop = -1;
338 static int infinite_buffer = -1;
339 static enum ShowMode show_mode = SHOW_MODE_NONE;
340 static const char *audio_codec_name;
341 static const char *subtitle_codec_name;
342 static const char *video_codec_name;
343 double rdftspeed = 0.02;
344 static int64_t cursor_last_shown;
345 static int cursor_hidden = 0;
347 static const char **vfilters_list = NULL;
348 static int nb_vfilters = 0;
349 static char *afilters = NULL;
351 static int autorotate = 1;
352 static int find_stream_info = 1;
354 /* current context */
355 static int is_full_screen;
356 static int64_t audio_callback_time;
358 static AVPacket flush_pkt;
360 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
362 static SDL_Window *window;
363 static SDL_Renderer *renderer;
364 static SDL_RendererInfo renderer_info = {0};
365 static SDL_AudioDeviceID audio_dev;
367 static const struct TextureFormatEntry {
368 enum AVPixelFormat format;
370 } sdl_texture_format_map[] = {
371 { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 },
372 { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 },
373 { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 },
374 { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 },
375 { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 },
376 { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 },
377 { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 },
378 { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 },
379 { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 },
380 { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 },
381 { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 },
382 { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 },
383 { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 },
384 { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 },
385 { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 },
386 { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 },
387 { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV },
388 { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 },
389 { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY },
390 { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN },
394 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
396 GROW_ARRAY(vfilters_list, nb_vfilters);
397 vfilters_list[nb_vfilters - 1] = arg;
403 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
404 enum AVSampleFormat fmt2, int64_t channel_count2)
406 /* If channel count == 1, planar and non-planar formats are the same */
407 if (channel_count1 == 1 && channel_count2 == 1)
408 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
410 return channel_count1 != channel_count2 || fmt1 != fmt2;
414 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
416 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
417 return channel_layout;
422 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
424 MyAVPacketList *pkt1;
426 if (q->abort_request)
429 pkt1 = av_malloc(sizeof(MyAVPacketList));
434 if (pkt == &flush_pkt)
436 pkt1->serial = q->serial;
441 q->last_pkt->next = pkt1;
444 q->size += pkt1->pkt.size + sizeof(*pkt1);
445 q->duration += pkt1->pkt.duration;
446 /* XXX: should duplicate packet data in DV case */
447 SDL_CondSignal(q->cond);
451 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
455 SDL_LockMutex(q->mutex);
456 ret = packet_queue_put_private(q, pkt);
457 SDL_UnlockMutex(q->mutex);
459 if (pkt != &flush_pkt && ret < 0)
460 av_packet_unref(pkt);
465 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
467 AVPacket pkt1, *pkt = &pkt1;
471 pkt->stream_index = stream_index;
472 return packet_queue_put(q, pkt);
475 /* packet queue handling */
476 static int packet_queue_init(PacketQueue *q)
478 memset(q, 0, sizeof(PacketQueue));
479 q->mutex = SDL_CreateMutex();
481 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
482 return AVERROR(ENOMEM);
484 q->cond = SDL_CreateCond();
486 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
487 return AVERROR(ENOMEM);
489 q->abort_request = 1;
493 static void packet_queue_flush(PacketQueue *q)
495 MyAVPacketList *pkt, *pkt1;
497 SDL_LockMutex(q->mutex);
498 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
500 av_packet_unref(&pkt->pkt);
508 SDL_UnlockMutex(q->mutex);
511 static void packet_queue_destroy(PacketQueue *q)
513 packet_queue_flush(q);
514 SDL_DestroyMutex(q->mutex);
515 SDL_DestroyCond(q->cond);
518 static void packet_queue_abort(PacketQueue *q)
520 SDL_LockMutex(q->mutex);
522 q->abort_request = 1;
524 SDL_CondSignal(q->cond);
526 SDL_UnlockMutex(q->mutex);
529 static void packet_queue_start(PacketQueue *q)
531 SDL_LockMutex(q->mutex);
532 q->abort_request = 0;
533 packet_queue_put_private(q, &flush_pkt);
534 SDL_UnlockMutex(q->mutex);
537 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
538 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
540 MyAVPacketList *pkt1;
543 SDL_LockMutex(q->mutex);
546 if (q->abort_request) {
553 q->first_pkt = pkt1->next;
557 q->size -= pkt1->pkt.size + sizeof(*pkt1);
558 q->duration -= pkt1->pkt.duration;
561 *serial = pkt1->serial;
569 SDL_CondWait(q->cond, q->mutex);
572 SDL_UnlockMutex(q->mutex);
576 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
577 memset(d, 0, sizeof(Decoder));
580 d->empty_queue_cond = empty_queue_cond;
581 d->start_pts = AV_NOPTS_VALUE;
585 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
586 int ret = AVERROR(EAGAIN);
591 if (d->queue->serial == d->pkt_serial) {
593 if (d->queue->abort_request)
596 switch (d->avctx->codec_type) {
597 case AVMEDIA_TYPE_VIDEO:
598 ret = avcodec_receive_frame(d->avctx, frame);
600 if (decoder_reorder_pts == -1) {
601 frame->pts = frame->best_effort_timestamp;
602 } else if (!decoder_reorder_pts) {
603 frame->pts = frame->pkt_dts;
607 case AVMEDIA_TYPE_AUDIO:
608 ret = avcodec_receive_frame(d->avctx, frame);
610 AVRational tb = (AVRational){1, frame->sample_rate};
611 if (frame->pts != AV_NOPTS_VALUE)
612 frame->pts = av_rescale_q(frame->pts, d->avctx->pkt_timebase, tb);
613 else if (d->next_pts != AV_NOPTS_VALUE)
614 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
615 if (frame->pts != AV_NOPTS_VALUE) {
616 d->next_pts = frame->pts + frame->nb_samples;
622 if (ret == AVERROR_EOF) {
623 d->finished = d->pkt_serial;
624 avcodec_flush_buffers(d->avctx);
629 } while (ret != AVERROR(EAGAIN));
633 if (d->queue->nb_packets == 0)
634 SDL_CondSignal(d->empty_queue_cond);
635 if (d->packet_pending) {
636 av_packet_move_ref(&pkt, &d->pkt);
637 d->packet_pending = 0;
639 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
642 } while (d->queue->serial != d->pkt_serial);
644 if (pkt.data == flush_pkt.data) {
645 avcodec_flush_buffers(d->avctx);
647 d->next_pts = d->start_pts;
648 d->next_pts_tb = d->start_pts_tb;
650 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
652 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
654 ret = AVERROR(EAGAIN);
656 if (got_frame && !pkt.data) {
657 d->packet_pending = 1;
658 av_packet_move_ref(&d->pkt, &pkt);
660 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
663 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
664 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
665 d->packet_pending = 1;
666 av_packet_move_ref(&d->pkt, &pkt);
669 av_packet_unref(&pkt);
674 static void decoder_destroy(Decoder *d) {
675 av_packet_unref(&d->pkt);
676 avcodec_free_context(&d->avctx);
679 static void frame_queue_unref_item(Frame *vp)
681 av_frame_unref(vp->frame);
682 avsubtitle_free(&vp->sub);
685 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
688 memset(f, 0, sizeof(FrameQueue));
689 if (!(f->mutex = SDL_CreateMutex())) {
690 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
691 return AVERROR(ENOMEM);
693 if (!(f->cond = SDL_CreateCond())) {
694 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
695 return AVERROR(ENOMEM);
698 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
699 f->keep_last = !!keep_last;
700 for (i = 0; i < f->max_size; i++)
701 if (!(f->queue[i].frame = av_frame_alloc()))
702 return AVERROR(ENOMEM);
706 static void frame_queue_destory(FrameQueue *f)
709 for (i = 0; i < f->max_size; i++) {
710 Frame *vp = &f->queue[i];
711 frame_queue_unref_item(vp);
712 av_frame_free(&vp->frame);
714 SDL_DestroyMutex(f->mutex);
715 SDL_DestroyCond(f->cond);
718 static void frame_queue_signal(FrameQueue *f)
720 SDL_LockMutex(f->mutex);
721 SDL_CondSignal(f->cond);
722 SDL_UnlockMutex(f->mutex);
725 static Frame *frame_queue_peek(FrameQueue *f)
727 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
730 static Frame *frame_queue_peek_next(FrameQueue *f)
732 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
735 static Frame *frame_queue_peek_last(FrameQueue *f)
737 return &f->queue[f->rindex];
740 static Frame *frame_queue_peek_writable(FrameQueue *f)
742 /* wait until we have space to put a new frame */
743 SDL_LockMutex(f->mutex);
744 while (f->size >= f->max_size &&
745 !f->pktq->abort_request) {
746 SDL_CondWait(f->cond, f->mutex);
748 SDL_UnlockMutex(f->mutex);
750 if (f->pktq->abort_request)
753 return &f->queue[f->windex];
756 static Frame *frame_queue_peek_readable(FrameQueue *f)
758 /* wait until we have a readable a new frame */
759 SDL_LockMutex(f->mutex);
760 while (f->size - f->rindex_shown <= 0 &&
761 !f->pktq->abort_request) {
762 SDL_CondWait(f->cond, f->mutex);
764 SDL_UnlockMutex(f->mutex);
766 if (f->pktq->abort_request)
769 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
772 static void frame_queue_push(FrameQueue *f)
774 if (++f->windex == f->max_size)
776 SDL_LockMutex(f->mutex);
778 SDL_CondSignal(f->cond);
779 SDL_UnlockMutex(f->mutex);
782 static void frame_queue_next(FrameQueue *f)
784 if (f->keep_last && !f->rindex_shown) {
788 frame_queue_unref_item(&f->queue[f->rindex]);
789 if (++f->rindex == f->max_size)
791 SDL_LockMutex(f->mutex);
793 SDL_CondSignal(f->cond);
794 SDL_UnlockMutex(f->mutex);
797 /* return the number of undisplayed frames in the queue */
798 static int frame_queue_nb_remaining(FrameQueue *f)
800 return f->size - f->rindex_shown;
803 /* return last shown position */
804 static int64_t frame_queue_last_pos(FrameQueue *f)
806 Frame *fp = &f->queue[f->rindex];
807 if (f->rindex_shown && fp->serial == f->pktq->serial)
813 static void decoder_abort(Decoder *d, FrameQueue *fq)
815 packet_queue_abort(d->queue);
816 frame_queue_signal(fq);
817 SDL_WaitThread(d->decoder_tid, NULL);
818 d->decoder_tid = NULL;
819 packet_queue_flush(d->queue);
822 static inline void fill_rectangle(int x, int y, int w, int h)
830 SDL_RenderFillRect(renderer, &rect);
833 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
837 if (!*texture || SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
841 SDL_DestroyTexture(*texture);
842 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
844 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
847 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
849 memset(pixels, 0, pitch * new_height);
850 SDL_UnlockTexture(*texture);
852 av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
857 static void calculate_display_rect(SDL_Rect *rect,
858 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
859 int pic_width, int pic_height, AVRational pic_sar)
862 int width, height, x, y;
864 if (pic_sar.num == 0)
867 aspect_ratio = av_q2d(pic_sar);
869 if (aspect_ratio <= 0.0)
871 aspect_ratio *= (float)pic_width / (float)pic_height;
873 /* XXX: we suppose the screen has a 1.0 pixel ratio */
875 width = lrint(height * aspect_ratio) & ~1;
876 if (width > scr_width) {
878 height = lrint(width / aspect_ratio) & ~1;
880 x = (scr_width - width) / 2;
881 y = (scr_height - height) / 2;
882 rect->x = scr_xleft + x;
883 rect->y = scr_ytop + y;
884 rect->w = FFMAX(width, 1);
885 rect->h = FFMAX(height, 1);
888 static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
891 *sdl_blendmode = SDL_BLENDMODE_NONE;
892 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
893 if (format == AV_PIX_FMT_RGB32 ||
894 format == AV_PIX_FMT_RGB32_1 ||
895 format == AV_PIX_FMT_BGR32 ||
896 format == AV_PIX_FMT_BGR32_1)
897 *sdl_blendmode = SDL_BLENDMODE_BLEND;
898 for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
899 if (format == sdl_texture_format_map[i].format) {
900 *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
906 static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
909 SDL_BlendMode sdl_blendmode;
910 get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
911 if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
913 switch (sdl_pix_fmt) {
914 case SDL_PIXELFORMAT_UNKNOWN:
915 /* This should only happen if we are not using avfilter... */
916 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
917 frame->width, frame->height, frame->format, frame->width, frame->height,
918 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
919 if (*img_convert_ctx != NULL) {
922 if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
923 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
924 0, frame->height, pixels, pitch);
925 SDL_UnlockTexture(*tex);
928 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
932 case SDL_PIXELFORMAT_IYUV:
933 if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
934 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
935 frame->data[1], frame->linesize[1],
936 frame->data[2], frame->linesize[2]);
937 } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) {
938 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0],
939 frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
940 frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
942 av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
947 if (frame->linesize[0] < 0) {
948 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
950 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
957 static void set_sdl_yuv_conversion_mode(AVFrame *frame)
959 #if SDL_VERSION_ATLEAST(2,0,8)
960 SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
961 if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
962 if (frame->color_range == AVCOL_RANGE_JPEG)
963 mode = SDL_YUV_CONVERSION_JPEG;
964 else if (frame->colorspace == AVCOL_SPC_BT709)
965 mode = SDL_YUV_CONVERSION_BT709;
966 else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
967 mode = SDL_YUV_CONVERSION_BT601;
969 SDL_SetYUVConversionMode(mode);
973 static void video_image_display(VideoState *is)
979 vp = frame_queue_peek_last(&is->pictq);
980 if (is->subtitle_st) {
981 if (frame_queue_nb_remaining(&is->subpq) > 0) {
982 sp = frame_queue_peek(&is->subpq);
984 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
989 if (!sp->width || !sp->height) {
990 sp->width = vp->width;
991 sp->height = vp->height;
993 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
996 for (i = 0; i < sp->sub.num_rects; i++) {
997 AVSubtitleRect *sub_rect = sp->sub.rects[i];
999 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
1000 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
1001 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
1002 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
1004 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
1005 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
1006 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
1007 0, NULL, NULL, NULL);
1008 if (!is->sub_convert_ctx) {
1009 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1012 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
1013 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
1014 0, sub_rect->h, pixels, pitch);
1015 SDL_UnlockTexture(is->sub_texture);
1025 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1027 if (!vp->uploaded) {
1028 if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
1031 vp->flip_v = vp->frame->linesize[0] < 0;
1034 set_sdl_yuv_conversion_mode(vp->frame);
1035 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
1036 set_sdl_yuv_conversion_mode(NULL);
1038 #if USE_ONEPASS_SUBTITLE_RENDER
1039 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
1042 double xratio = (double)rect.w / (double)sp->width;
1043 double yratio = (double)rect.h / (double)sp->height;
1044 for (i = 0; i < sp->sub.num_rects; i++) {
1045 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
1046 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
1047 .y = rect.y + sub_rect->y * yratio,
1048 .w = sub_rect->w * xratio,
1049 .h = sub_rect->h * yratio};
1050 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
1056 static inline int compute_mod(int a, int b)
1058 return a < 0 ? a%b + b : a%b;
1061 static void video_audio_display(VideoState *s)
1063 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1064 int ch, channels, h, h2;
1066 int rdft_bits, nb_freq;
1068 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1070 nb_freq = 1 << (rdft_bits - 1);
1072 /* compute display index : center on currently output samples */
1073 channels = s->audio_tgt.channels;
1074 nb_display_channels = channels;
1076 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1078 delay = s->audio_write_buf_size;
1081 /* to be more precise, we take into account the time spent since
1082 the last buffer computation */
1083 if (audio_callback_time) {
1084 time_diff = av_gettime_relative() - audio_callback_time;
1085 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1088 delay += 2 * data_used;
1089 if (delay < data_used)
1092 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1093 if (s->show_mode == SHOW_MODE_WAVES) {
1095 for (i = 0; i < 1000; i += channels) {
1096 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1097 int a = s->sample_array[idx];
1098 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1099 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1100 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1102 if (h < score && (b ^ c) < 0) {
1109 s->last_i_start = i_start;
1111 i_start = s->last_i_start;
1114 if (s->show_mode == SHOW_MODE_WAVES) {
1115 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1117 /* total height for one channel */
1118 h = s->height / nb_display_channels;
1119 /* graph height / 2 */
1121 for (ch = 0; ch < nb_display_channels; ch++) {
1123 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1124 for (x = 0; x < s->width; x++) {
1125 y = (s->sample_array[i] * h2) >> 15;
1132 fill_rectangle(s->xleft + x, ys, 1, y);
1134 if (i >= SAMPLE_ARRAY_SIZE)
1135 i -= SAMPLE_ARRAY_SIZE;
1139 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1141 for (ch = 1; ch < nb_display_channels; ch++) {
1142 y = s->ytop + ch * h;
1143 fill_rectangle(s->xleft, y, s->width, 1);
1146 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1149 nb_display_channels= FFMIN(nb_display_channels, 2);
1150 if (rdft_bits != s->rdft_bits) {
1151 av_rdft_end(s->rdft);
1152 av_free(s->rdft_data);
1153 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1154 s->rdft_bits = rdft_bits;
1155 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1157 if (!s->rdft || !s->rdft_data){
1158 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1159 s->show_mode = SHOW_MODE_WAVES;
1162 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1165 for (ch = 0; ch < nb_display_channels; ch++) {
1166 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1168 for (x = 0; x < 2 * nb_freq; x++) {
1169 double w = (x-nb_freq) * (1.0 / nb_freq);
1170 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1172 if (i >= SAMPLE_ARRAY_SIZE)
1173 i -= SAMPLE_ARRAY_SIZE;
1175 av_rdft_calc(s->rdft, data[ch]);
1177 /* Least efficient way to do this, we should of course
1178 * directly access it but it is more than fast enough. */
1179 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1181 pixels += pitch * s->height;
1182 for (y = 0; y < s->height; y++) {
1183 double w = 1 / sqrt(nb_freq);
1184 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
1185 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1190 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1192 SDL_UnlockTexture(s->vis_texture);
1194 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1198 if (s->xpos >= s->width)
1203 static void stream_component_close(VideoState *is, int stream_index)
1205 AVFormatContext *ic = is->ic;
1206 AVCodecParameters *codecpar;
1208 if (stream_index < 0 || stream_index >= ic->nb_streams)
1210 codecpar = ic->streams[stream_index]->codecpar;
1212 switch (codecpar->codec_type) {
1213 case AVMEDIA_TYPE_AUDIO:
1214 decoder_abort(&is->auddec, &is->sampq);
1215 SDL_CloseAudioDevice(audio_dev);
1216 decoder_destroy(&is->auddec);
1217 swr_free(&is->swr_ctx);
1218 av_freep(&is->audio_buf1);
1219 is->audio_buf1_size = 0;
1220 is->audio_buf = NULL;
1223 av_rdft_end(is->rdft);
1224 av_freep(&is->rdft_data);
1229 case AVMEDIA_TYPE_VIDEO:
1230 decoder_abort(&is->viddec, &is->pictq);
1231 decoder_destroy(&is->viddec);
1233 case AVMEDIA_TYPE_SUBTITLE:
1234 decoder_abort(&is->subdec, &is->subpq);
1235 decoder_destroy(&is->subdec);
1241 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1242 switch (codecpar->codec_type) {
1243 case AVMEDIA_TYPE_AUDIO:
1244 is->audio_st = NULL;
1245 is->audio_stream = -1;
1247 case AVMEDIA_TYPE_VIDEO:
1248 is->video_st = NULL;
1249 is->video_stream = -1;
1251 case AVMEDIA_TYPE_SUBTITLE:
1252 is->subtitle_st = NULL;
1253 is->subtitle_stream = -1;
1260 static void stream_close(VideoState *is)
1262 /* XXX: use a special url_shutdown call to abort parse cleanly */
1263 is->abort_request = 1;
1264 SDL_WaitThread(is->read_tid, NULL);
1266 /* close each stream */
1267 if (is->audio_stream >= 0)
1268 stream_component_close(is, is->audio_stream);
1269 if (is->video_stream >= 0)
1270 stream_component_close(is, is->video_stream);
1271 if (is->subtitle_stream >= 0)
1272 stream_component_close(is, is->subtitle_stream);
1274 avformat_close_input(&is->ic);
1276 packet_queue_destroy(&is->videoq);
1277 packet_queue_destroy(&is->audioq);
1278 packet_queue_destroy(&is->subtitleq);
1280 /* free all pictures */
1281 frame_queue_destory(&is->pictq);
1282 frame_queue_destory(&is->sampq);
1283 frame_queue_destory(&is->subpq);
1284 SDL_DestroyCond(is->continue_read_thread);
1285 sws_freeContext(is->img_convert_ctx);
1286 sws_freeContext(is->sub_convert_ctx);
1287 av_free(is->filename);
1288 if (is->vis_texture)
1289 SDL_DestroyTexture(is->vis_texture);
1290 if (is->vid_texture)
1291 SDL_DestroyTexture(is->vid_texture);
1292 if (is->sub_texture)
1293 SDL_DestroyTexture(is->sub_texture);
1297 static void do_exit(VideoState *is)
1303 SDL_DestroyRenderer(renderer);
1305 SDL_DestroyWindow(window);
1308 av_freep(&vfilters_list);
1310 avformat_network_deinit();
1314 av_log(NULL, AV_LOG_QUIET, "%s", "");
1318 static void sigterm_handler(int sig)
1323 static void set_default_window_size(int width, int height, AVRational sar)
1326 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1327 default_width = rect.w;
1328 default_height = rect.h;
1331 static int video_open(VideoState *is)
1344 window_title = input_filename;
1345 SDL_SetWindowTitle(window, window_title);
1347 SDL_SetWindowSize(window, w, h);
1348 SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
1350 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1351 SDL_ShowWindow(window);
1359 /* display the current picture, if any */
1360 static void video_display(VideoState *is)
1365 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1366 SDL_RenderClear(renderer);
1367 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1368 video_audio_display(is);
1369 else if (is->video_st)
1370 video_image_display(is);
1371 SDL_RenderPresent(renderer);
1374 static double get_clock(Clock *c)
1376 if (*c->queue_serial != c->serial)
1381 double time = av_gettime_relative() / 1000000.0;
1382 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1386 static void set_clock_at(Clock *c, double pts, int serial, double time)
1389 c->last_updated = time;
1390 c->pts_drift = c->pts - time;
1394 static void set_clock(Clock *c, double pts, int serial)
1396 double time = av_gettime_relative() / 1000000.0;
1397 set_clock_at(c, pts, serial, time);
1400 static void set_clock_speed(Clock *c, double speed)
1402 set_clock(c, get_clock(c), c->serial);
1406 static void init_clock(Clock *c, int *queue_serial)
1410 c->queue_serial = queue_serial;
1411 set_clock(c, NAN, -1);
1414 static void sync_clock_to_slave(Clock *c, Clock *slave)
1416 double clock = get_clock(c);
1417 double slave_clock = get_clock(slave);
1418 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1419 set_clock(c, slave_clock, slave->serial);
1422 static int get_master_sync_type(VideoState *is) {
1423 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1425 return AV_SYNC_VIDEO_MASTER;
1427 return AV_SYNC_AUDIO_MASTER;
1428 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1430 return AV_SYNC_AUDIO_MASTER;
1432 return AV_SYNC_EXTERNAL_CLOCK;
1434 return AV_SYNC_EXTERNAL_CLOCK;
1438 /* get the current master clock value */
1439 static double get_master_clock(VideoState *is)
1443 switch (get_master_sync_type(is)) {
1444 case AV_SYNC_VIDEO_MASTER:
1445 val = get_clock(&is->vidclk);
1447 case AV_SYNC_AUDIO_MASTER:
1448 val = get_clock(&is->audclk);
1451 val = get_clock(&is->extclk);
1457 static void check_external_clock_speed(VideoState *is) {
1458 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1459 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1460 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1461 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1462 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1463 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1465 double speed = is->extclk.speed;
1467 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1471 /* seek in the stream */
1472 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1474 if (!is->seek_req) {
1477 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1479 is->seek_flags |= AVSEEK_FLAG_BYTE;
1481 SDL_CondSignal(is->continue_read_thread);
1485 /* pause or resume the video */
1486 static void stream_toggle_pause(VideoState *is)
1489 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1490 if (is->read_pause_return != AVERROR(ENOSYS)) {
1491 is->vidclk.paused = 0;
1493 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1495 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1496 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1499 static void toggle_pause(VideoState *is)
1501 stream_toggle_pause(is);
1505 static void toggle_mute(VideoState *is)
1507 is->muted = !is->muted;
1510 static void update_volume(VideoState *is, int sign, double step)
1512 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1513 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1514 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1517 static void step_to_next_frame(VideoState *is)
1519 /* if the stream is paused unpause it, then step */
1521 stream_toggle_pause(is);
1525 static double compute_target_delay(double delay, VideoState *is)
1527 double sync_threshold, diff = 0;
1529 /* update delay to follow master synchronisation source */
1530 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1531 /* if video is slave, we try to correct big delays by
1532 duplicating or deleting a frame */
1533 diff = get_clock(&is->vidclk) - get_master_clock(is);
1535 /* skip or repeat frame. We take into account the
1536 delay to compute the threshold. I still don't know
1537 if it is the best guess */
1538 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1539 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1540 if (diff <= -sync_threshold)
1541 delay = FFMAX(0, delay + diff);
1542 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1543 delay = delay + diff;
1544 else if (diff >= sync_threshold)
1549 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1555 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1556 if (vp->serial == nextvp->serial) {
1557 double duration = nextvp->pts - vp->pts;
1558 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1559 return vp->duration;
1567 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1568 /* update current video pts */
1569 set_clock(&is->vidclk, pts, serial);
1570 sync_clock_to_slave(&is->extclk, &is->vidclk);
1573 /* called to display each frame */
1574 static void video_refresh(void *opaque, double *remaining_time)
1576 VideoState *is = opaque;
1581 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1582 check_external_clock_speed(is);
1584 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1585 time = av_gettime_relative() / 1000000.0;
1586 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1588 is->last_vis_time = time;
1590 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1595 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1596 // nothing to do, no picture to display in the queue
1598 double last_duration, duration, delay;
1601 /* dequeue the picture */
1602 lastvp = frame_queue_peek_last(&is->pictq);
1603 vp = frame_queue_peek(&is->pictq);
1605 if (vp->serial != is->videoq.serial) {
1606 frame_queue_next(&is->pictq);
1610 if (lastvp->serial != vp->serial)
1611 is->frame_timer = av_gettime_relative() / 1000000.0;
1616 /* compute nominal last_duration */
1617 last_duration = vp_duration(is, lastvp, vp);
1618 delay = compute_target_delay(last_duration, is);
1620 time= av_gettime_relative()/1000000.0;
1621 if (time < is->frame_timer + delay) {
1622 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1626 is->frame_timer += delay;
1627 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1628 is->frame_timer = time;
1630 SDL_LockMutex(is->pictq.mutex);
1631 if (!isnan(vp->pts))
1632 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1633 SDL_UnlockMutex(is->pictq.mutex);
1635 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1636 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1637 duration = vp_duration(is, vp, nextvp);
1638 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1639 is->frame_drops_late++;
1640 frame_queue_next(&is->pictq);
1645 if (is->subtitle_st) {
1646 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1647 sp = frame_queue_peek(&is->subpq);
1649 if (frame_queue_nb_remaining(&is->subpq) > 1)
1650 sp2 = frame_queue_peek_next(&is->subpq);
1654 if (sp->serial != is->subtitleq.serial
1655 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1656 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1660 for (i = 0; i < sp->sub.num_rects; i++) {
1661 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1665 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1666 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1667 memset(pixels, 0, sub_rect->w << 2);
1668 SDL_UnlockTexture(is->sub_texture);
1672 frame_queue_next(&is->subpq);
1679 frame_queue_next(&is->pictq);
1680 is->force_refresh = 1;
1682 if (is->step && !is->paused)
1683 stream_toggle_pause(is);
1686 /* display picture */
1687 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1690 is->force_refresh = 0;
1692 static int64_t last_time;
1694 int aqsize, vqsize, sqsize;
1697 cur_time = av_gettime_relative();
1698 if (!last_time || (cur_time - last_time) >= 30000) {
1703 aqsize = is->audioq.size;
1705 vqsize = is->videoq.size;
1706 if (is->subtitle_st)
1707 sqsize = is->subtitleq.size;
1709 if (is->audio_st && is->video_st)
1710 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1711 else if (is->video_st)
1712 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1713 else if (is->audio_st)
1714 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1715 av_log(NULL, AV_LOG_INFO,
1716 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1717 get_master_clock(is),
1718 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1720 is->frame_drops_early + is->frame_drops_late,
1724 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1725 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1727 last_time = cur_time;
1732 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1736 #if defined(DEBUG_SYNC)
1737 printf("frame_type=%c pts=%0.3f\n",
1738 av_get_picture_type_char(src_frame->pict_type), pts);
1741 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1744 vp->sar = src_frame->sample_aspect_ratio;
1747 vp->width = src_frame->width;
1748 vp->height = src_frame->height;
1749 vp->format = src_frame->format;
1752 vp->duration = duration;
1754 vp->serial = serial;
1756 set_default_window_size(vp->width, vp->height, vp->sar);
1758 av_frame_move_ref(vp->frame, src_frame);
1759 frame_queue_push(&is->pictq);
1763 static int get_video_frame(VideoState *is, AVFrame *frame)
1767 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1773 if (frame->pts != AV_NOPTS_VALUE)
1774 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1776 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1778 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1779 if (frame->pts != AV_NOPTS_VALUE) {
1780 double diff = dpts - get_master_clock(is);
1781 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1782 diff - is->frame_last_filter_delay < 0 &&
1783 is->viddec.pkt_serial == is->vidclk.serial &&
1784 is->videoq.nb_packets) {
1785 is->frame_drops_early++;
1786 av_frame_unref(frame);
1797 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1798 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1801 int nb_filters = graph->nb_filters;
1802 AVFilterInOut *outputs = NULL, *inputs = NULL;
1805 outputs = avfilter_inout_alloc();
1806 inputs = avfilter_inout_alloc();
1807 if (!outputs || !inputs) {
1808 ret = AVERROR(ENOMEM);
1812 outputs->name = av_strdup("in");
1813 outputs->filter_ctx = source_ctx;
1814 outputs->pad_idx = 0;
1815 outputs->next = NULL;
1817 inputs->name = av_strdup("out");
1818 inputs->filter_ctx = sink_ctx;
1819 inputs->pad_idx = 0;
1820 inputs->next = NULL;
1822 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1825 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1829 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1830 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1831 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1833 ret = avfilter_graph_config(graph, NULL);
1835 avfilter_inout_free(&outputs);
1836 avfilter_inout_free(&inputs);
1840 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1842 enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
1843 char sws_flags_str[512] = "";
1844 char buffersrc_args[256];
1846 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1847 AVCodecParameters *codecpar = is->video_st->codecpar;
1848 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1849 AVDictionaryEntry *e = NULL;
1850 int nb_pix_fmts = 0;
1853 for (i = 0; i < renderer_info.num_texture_formats; i++) {
1854 for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; j++) {
1855 if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
1856 pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
1861 pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
1863 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1864 if (!strcmp(e->key, "sws_flags")) {
1865 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1867 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1869 if (strlen(sws_flags_str))
1870 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1872 graph->scale_sws_opts = av_strdup(sws_flags_str);
1874 snprintf(buffersrc_args, sizeof(buffersrc_args),
1875 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1876 frame->width, frame->height, frame->format,
1877 is->video_st->time_base.num, is->video_st->time_base.den,
1878 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1879 if (fr.num && fr.den)
1880 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1882 if ((ret = avfilter_graph_create_filter(&filt_src,
1883 avfilter_get_by_name("buffer"),
1884 "ffplay_buffer", buffersrc_args, NULL,
1888 ret = avfilter_graph_create_filter(&filt_out,
1889 avfilter_get_by_name("buffersink"),
1890 "ffplay_buffersink", NULL, NULL, graph);
1894 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1897 last_filter = filt_out;
1899 /* Note: this macro adds a filter before the lastly added filter, so the
1900 * processing order of the filters is in reverse */
1901 #define INSERT_FILT(name, arg) do { \
1902 AVFilterContext *filt_ctx; \
1904 ret = avfilter_graph_create_filter(&filt_ctx, \
1905 avfilter_get_by_name(name), \
1906 "ffplay_" name, arg, NULL, graph); \
1910 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1914 last_filter = filt_ctx; \
1918 double theta = get_rotation(is->video_st);
1920 if (fabs(theta - 90) < 1.0) {
1921 INSERT_FILT("transpose", "clock");
1922 } else if (fabs(theta - 180) < 1.0) {
1923 INSERT_FILT("hflip", NULL);
1924 INSERT_FILT("vflip", NULL);
1925 } else if (fabs(theta - 270) < 1.0) {
1926 INSERT_FILT("transpose", "cclock");
1927 } else if (fabs(theta) > 1.0) {
1928 char rotate_buf[64];
1929 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1930 INSERT_FILT("rotate", rotate_buf);
1934 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1937 is->in_video_filter = filt_src;
1938 is->out_video_filter = filt_out;
1944 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1946 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1947 int sample_rates[2] = { 0, -1 };
1948 int64_t channel_layouts[2] = { 0, -1 };
1949 int channels[2] = { 0, -1 };
1950 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1951 char aresample_swr_opts[512] = "";
1952 AVDictionaryEntry *e = NULL;
1953 char asrc_args[256];
1956 avfilter_graph_free(&is->agraph);
1957 if (!(is->agraph = avfilter_graph_alloc()))
1958 return AVERROR(ENOMEM);
1960 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1961 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1962 if (strlen(aresample_swr_opts))
1963 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1964 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1966 ret = snprintf(asrc_args, sizeof(asrc_args),
1967 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1968 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1969 is->audio_filter_src.channels,
1970 1, is->audio_filter_src.freq);
1971 if (is->audio_filter_src.channel_layout)
1972 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1973 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1975 ret = avfilter_graph_create_filter(&filt_asrc,
1976 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1977 asrc_args, NULL, is->agraph);
1982 ret = avfilter_graph_create_filter(&filt_asink,
1983 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1984 NULL, NULL, is->agraph);
1988 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1990 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1993 if (force_output_format) {
1994 channel_layouts[0] = is->audio_tgt.channel_layout;
1995 channels [0] = is->audio_tgt.channels;
1996 sample_rates [0] = is->audio_tgt.freq;
1997 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1999 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2001 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2003 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2008 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2011 is->in_audio_filter = filt_asrc;
2012 is->out_audio_filter = filt_asink;
2016 avfilter_graph_free(&is->agraph);
2019 #endif /* CONFIG_AVFILTER */
2021 static int audio_thread(void *arg)
2023 VideoState *is = arg;
2024 AVFrame *frame = av_frame_alloc();
2027 int last_serial = -1;
2028 int64_t dec_channel_layout;
2036 return AVERROR(ENOMEM);
2039 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2043 tb = (AVRational){1, frame->sample_rate};
2046 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
2049 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2050 frame->format, frame->channels) ||
2051 is->audio_filter_src.channel_layout != dec_channel_layout ||
2052 is->audio_filter_src.freq != frame->sample_rate ||
2053 is->auddec.pkt_serial != last_serial;
2056 char buf1[1024], buf2[1024];
2057 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2058 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2059 av_log(NULL, AV_LOG_DEBUG,
2060 "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
2061 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2062 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2064 is->audio_filter_src.fmt = frame->format;
2065 is->audio_filter_src.channels = frame->channels;
2066 is->audio_filter_src.channel_layout = dec_channel_layout;
2067 is->audio_filter_src.freq = frame->sample_rate;
2068 last_serial = is->auddec.pkt_serial;
2070 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2074 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2077 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2078 tb = av_buffersink_get_time_base(is->out_audio_filter);
2080 if (!(af = frame_queue_peek_writable(&is->sampq)))
2083 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2084 af->pos = frame->pkt_pos;
2085 af->serial = is->auddec.pkt_serial;
2086 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2088 av_frame_move_ref(af->frame, frame);
2089 frame_queue_push(&is->sampq);
2092 if (is->audioq.serial != is->auddec.pkt_serial)
2095 if (ret == AVERROR_EOF)
2096 is->auddec.finished = is->auddec.pkt_serial;
2099 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2102 avfilter_graph_free(&is->agraph);
2104 av_frame_free(&frame);
2108 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2110 packet_queue_start(d->queue);
2111 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2112 if (!d->decoder_tid) {
2113 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2114 return AVERROR(ENOMEM);
2119 static int video_thread(void *arg)
2121 VideoState *is = arg;
2122 AVFrame *frame = av_frame_alloc();
2126 AVRational tb = is->video_st->time_base;
2127 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2130 AVFilterGraph *graph = avfilter_graph_alloc();
2131 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2134 enum AVPixelFormat last_format = -2;
2135 int last_serial = -1;
2136 int last_vfilter_idx = 0;
2138 av_frame_free(&frame);
2139 return AVERROR(ENOMEM);
2146 avfilter_graph_free(&graph);
2148 return AVERROR(ENOMEM);
2152 ret = get_video_frame(is, frame);
2159 if ( last_w != frame->width
2160 || last_h != frame->height
2161 || last_format != frame->format
2162 || last_serial != is->viddec.pkt_serial
2163 || last_vfilter_idx != is->vfilter_idx) {
2164 av_log(NULL, AV_LOG_DEBUG,
2165 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2167 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2168 frame->width, frame->height,
2169 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2170 avfilter_graph_free(&graph);
2171 graph = avfilter_graph_alloc();
2172 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2174 event.type = FF_QUIT_EVENT;
2175 event.user.data1 = is;
2176 SDL_PushEvent(&event);
2179 filt_in = is->in_video_filter;
2180 filt_out = is->out_video_filter;
2181 last_w = frame->width;
2182 last_h = frame->height;
2183 last_format = frame->format;
2184 last_serial = is->viddec.pkt_serial;
2185 last_vfilter_idx = is->vfilter_idx;
2186 frame_rate = av_buffersink_get_frame_rate(filt_out);
2189 ret = av_buffersrc_add_frame(filt_in, frame);
2194 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2196 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2198 if (ret == AVERROR_EOF)
2199 is->viddec.finished = is->viddec.pkt_serial;
2204 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2205 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2206 is->frame_last_filter_delay = 0;
2207 tb = av_buffersink_get_time_base(filt_out);
2209 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2210 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2211 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2212 av_frame_unref(frame);
2214 if (is->videoq.serial != is->viddec.pkt_serial)
2224 avfilter_graph_free(&graph);
2226 av_frame_free(&frame);
2230 static int subtitle_thread(void *arg)
2232 VideoState *is = arg;
2238 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2241 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2246 if (got_subtitle && sp->sub.format == 0) {
2247 if (sp->sub.pts != AV_NOPTS_VALUE)
2248 pts = sp->sub.pts / (double)AV_TIME_BASE;
2250 sp->serial = is->subdec.pkt_serial;
2251 sp->width = is->subdec.avctx->width;
2252 sp->height = is->subdec.avctx->height;
2255 /* now we can update the picture count */
2256 frame_queue_push(&is->subpq);
2257 } else if (got_subtitle) {
2258 avsubtitle_free(&sp->sub);
2264 /* copy samples for viewing in editor window */
2265 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2269 size = samples_size / sizeof(short);
2271 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2274 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2276 is->sample_array_index += len;
2277 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2278 is->sample_array_index = 0;
2283 /* return the wanted number of samples to get better sync if sync_type is video
2284 * or external master clock */
2285 static int synchronize_audio(VideoState *is, int nb_samples)
2287 int wanted_nb_samples = nb_samples;
2289 /* if not master, then we try to remove or add samples to correct the clock */
2290 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2291 double diff, avg_diff;
2292 int min_nb_samples, max_nb_samples;
2294 diff = get_clock(&is->audclk) - get_master_clock(is);
2296 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2297 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2298 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2299 /* not enough measures to have a correct estimate */
2300 is->audio_diff_avg_count++;
2302 /* estimate the A-V difference */
2303 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2305 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2306 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2307 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2308 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2309 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2311 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2312 diff, avg_diff, wanted_nb_samples - nb_samples,
2313 is->audio_clock, is->audio_diff_threshold);
2316 /* too big difference : may be initial PTS errors, so
2318 is->audio_diff_avg_count = 0;
2319 is->audio_diff_cum = 0;
2323 return wanted_nb_samples;
2327 * Decode one audio frame and return its uncompressed size.
2329 * The processed audio frame is decoded, converted if required, and
2330 * stored in is->audio_buf, with size in bytes given by the return
2333 static int audio_decode_frame(VideoState *is)
2335 int data_size, resampled_data_size;
2336 int64_t dec_channel_layout;
2337 av_unused double audio_clock0;
2338 int wanted_nb_samples;
2346 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2347 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2352 if (!(af = frame_queue_peek_readable(&is->sampq)))
2354 frame_queue_next(&is->sampq);
2355 } while (af->serial != is->audioq.serial);
2357 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2358 af->frame->nb_samples,
2359 af->frame->format, 1);
2361 dec_channel_layout =
2362 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2363 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2364 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2366 if (af->frame->format != is->audio_src.fmt ||
2367 dec_channel_layout != is->audio_src.channel_layout ||
2368 af->frame->sample_rate != is->audio_src.freq ||
2369 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2370 swr_free(&is->swr_ctx);
2371 is->swr_ctx = swr_alloc_set_opts(NULL,
2372 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2373 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2375 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2376 av_log(NULL, AV_LOG_ERROR,
2377 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2378 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2379 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2380 swr_free(&is->swr_ctx);
2383 is->audio_src.channel_layout = dec_channel_layout;
2384 is->audio_src.channels = af->frame->channels;
2385 is->audio_src.freq = af->frame->sample_rate;
2386 is->audio_src.fmt = af->frame->format;
2390 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2391 uint8_t **out = &is->audio_buf1;
2392 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2393 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2396 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2399 if (wanted_nb_samples != af->frame->nb_samples) {
2400 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2401 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2402 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2406 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2407 if (!is->audio_buf1)
2408 return AVERROR(ENOMEM);
2409 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2411 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2414 if (len2 == out_count) {
2415 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2416 if (swr_init(is->swr_ctx) < 0)
2417 swr_free(&is->swr_ctx);
2419 is->audio_buf = is->audio_buf1;
2420 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2422 is->audio_buf = af->frame->data[0];
2423 resampled_data_size = data_size;
2426 audio_clock0 = is->audio_clock;
2427 /* update the audio clock with the pts */
2428 if (!isnan(af->pts))
2429 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2431 is->audio_clock = NAN;
2432 is->audio_clock_serial = af->serial;
2435 static double last_clock;
2436 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2437 is->audio_clock - last_clock,
2438 is->audio_clock, audio_clock0);
2439 last_clock = is->audio_clock;
2442 return resampled_data_size;
2445 /* prepare a new audio buffer */
2446 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2448 VideoState *is = opaque;
2449 int audio_size, len1;
2451 audio_callback_time = av_gettime_relative();
2454 if (is->audio_buf_index >= is->audio_buf_size) {
2455 audio_size = audio_decode_frame(is);
2456 if (audio_size < 0) {
2457 /* if error, just output silence */
2458 is->audio_buf = NULL;
2459 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2461 if (is->show_mode != SHOW_MODE_VIDEO)
2462 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2463 is->audio_buf_size = audio_size;
2465 is->audio_buf_index = 0;
2467 len1 = is->audio_buf_size - is->audio_buf_index;
2470 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2471 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2473 memset(stream, 0, len1);
2474 if (!is->muted && is->audio_buf)
2475 SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
2479 is->audio_buf_index += len1;
2481 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2482 /* Let's assume the audio driver that is used by SDL has two periods. */
2483 if (!isnan(is->audio_clock)) {
2484 set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
2485 sync_clock_to_slave(&is->extclk, &is->audclk);
2489 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2491 SDL_AudioSpec wanted_spec, spec;
2493 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2494 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2495 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2497 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2499 wanted_nb_channels = atoi(env);
2500 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2502 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2503 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2504 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2506 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2507 wanted_spec.channels = wanted_nb_channels;
2508 wanted_spec.freq = wanted_sample_rate;
2509 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2510 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2513 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2514 next_sample_rate_idx--;
2515 wanted_spec.format = AUDIO_S16SYS;
2516 wanted_spec.silence = 0;
2517 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2518 wanted_spec.callback = sdl_audio_callback;
2519 wanted_spec.userdata = opaque;
2520 while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
2521 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2522 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2523 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2524 if (!wanted_spec.channels) {
2525 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2526 wanted_spec.channels = wanted_nb_channels;
2527 if (!wanted_spec.freq) {
2528 av_log(NULL, AV_LOG_ERROR,
2529 "No more combinations to try, audio open failed\n");
2533 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2535 if (spec.format != AUDIO_S16SYS) {
2536 av_log(NULL, AV_LOG_ERROR,
2537 "SDL advised audio format %d is not supported!\n", spec.format);
2540 if (spec.channels != wanted_spec.channels) {
2541 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2542 if (!wanted_channel_layout) {
2543 av_log(NULL, AV_LOG_ERROR,
2544 "SDL advised channel count %d is not supported!\n", spec.channels);
2549 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2550 audio_hw_params->freq = spec.freq;
2551 audio_hw_params->channel_layout = wanted_channel_layout;
2552 audio_hw_params->channels = spec.channels;
2553 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2554 audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
2555 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2556 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2562 /* open a given stream. Return 0 if OK */
2563 static int stream_component_open(VideoState *is, int stream_index)
2565 AVFormatContext *ic = is->ic;
2566 AVCodecContext *avctx;
2568 const char *forced_codec_name = NULL;
2569 AVDictionary *opts = NULL;
2570 AVDictionaryEntry *t = NULL;
2571 int sample_rate, nb_channels;
2572 int64_t channel_layout;
2574 int stream_lowres = lowres;
2576 if (stream_index < 0 || stream_index >= ic->nb_streams)
2579 avctx = avcodec_alloc_context3(NULL);
2581 return AVERROR(ENOMEM);
2583 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2586 avctx->pkt_timebase = ic->streams[stream_index]->time_base;
2588 codec = avcodec_find_decoder(avctx->codec_id);
2590 switch(avctx->codec_type){
2591 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2592 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2593 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2595 if (forced_codec_name)
2596 codec = avcodec_find_decoder_by_name(forced_codec_name);
2598 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2599 "No codec could be found with name '%s'\n", forced_codec_name);
2600 else av_log(NULL, AV_LOG_WARNING,
2601 "No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
2602 ret = AVERROR(EINVAL);
2606 avctx->codec_id = codec->id;
2607 if (stream_lowres > codec->max_lowres) {
2608 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2610 stream_lowres = codec->max_lowres;
2612 avctx->lowres = stream_lowres;
2615 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2617 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2618 if (!av_dict_get(opts, "threads", NULL, 0))
2619 av_dict_set(&opts, "threads", "auto", 0);
2621 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2622 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2623 av_dict_set(&opts, "refcounted_frames", "1", 0);
2624 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2627 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2628 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2629 ret = AVERROR_OPTION_NOT_FOUND;
2634 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2635 switch (avctx->codec_type) {
2636 case AVMEDIA_TYPE_AUDIO:
2639 AVFilterContext *sink;
2641 is->audio_filter_src.freq = avctx->sample_rate;
2642 is->audio_filter_src.channels = avctx->channels;
2643 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2644 is->audio_filter_src.fmt = avctx->sample_fmt;
2645 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2647 sink = is->out_audio_filter;
2648 sample_rate = av_buffersink_get_sample_rate(sink);
2649 nb_channels = av_buffersink_get_channels(sink);
2650 channel_layout = av_buffersink_get_channel_layout(sink);
2653 sample_rate = avctx->sample_rate;
2654 nb_channels = avctx->channels;
2655 channel_layout = avctx->channel_layout;
2658 /* prepare audio output */
2659 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2661 is->audio_hw_buf_size = ret;
2662 is->audio_src = is->audio_tgt;
2663 is->audio_buf_size = 0;
2664 is->audio_buf_index = 0;
2666 /* init averaging filter */
2667 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2668 is->audio_diff_avg_count = 0;
2669 /* since we do not have a precise anough audio FIFO fullness,
2670 we correct audio sync only if larger than this threshold */
2671 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2673 is->audio_stream = stream_index;
2674 is->audio_st = ic->streams[stream_index];
2676 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2677 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2678 is->auddec.start_pts = is->audio_st->start_time;
2679 is->auddec.start_pts_tb = is->audio_st->time_base;
2681 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2683 SDL_PauseAudioDevice(audio_dev, 0);
2685 case AVMEDIA_TYPE_VIDEO:
2686 is->video_stream = stream_index;
2687 is->video_st = ic->streams[stream_index];
2689 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2690 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2692 is->queue_attachments_req = 1;
2694 case AVMEDIA_TYPE_SUBTITLE:
2695 is->subtitle_stream = stream_index;
2696 is->subtitle_st = ic->streams[stream_index];
2698 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2699 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2708 avcodec_free_context(&avctx);
2710 av_dict_free(&opts);
2715 static int decode_interrupt_cb(void *ctx)
2717 VideoState *is = ctx;
2718 return is->abort_request;
2721 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2722 return stream_id < 0 ||
2723 queue->abort_request ||
2724 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2725 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2728 static int is_realtime(AVFormatContext *s)
2730 if( !strcmp(s->iformat->name, "rtp")
2731 || !strcmp(s->iformat->name, "rtsp")
2732 || !strcmp(s->iformat->name, "sdp")
2736 if(s->pb && ( !strncmp(s->url, "rtp:", 4)
2737 || !strncmp(s->url, "udp:", 4)
2744 /* this thread gets the stream from the disk or the network */
2745 static int read_thread(void *arg)
2747 VideoState *is = arg;
2748 AVFormatContext *ic = NULL;
2750 int st_index[AVMEDIA_TYPE_NB];
2751 AVPacket pkt1, *pkt = &pkt1;
2752 int64_t stream_start_time;
2753 int pkt_in_play_range = 0;
2754 AVDictionaryEntry *t;
2755 SDL_mutex *wait_mutex = SDL_CreateMutex();
2756 int scan_all_pmts_set = 0;
2760 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2761 ret = AVERROR(ENOMEM);
2765 memset(st_index, -1, sizeof(st_index));
2766 is->last_video_stream = is->video_stream = -1;
2767 is->last_audio_stream = is->audio_stream = -1;
2768 is->last_subtitle_stream = is->subtitle_stream = -1;
2771 ic = avformat_alloc_context();
2773 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2774 ret = AVERROR(ENOMEM);
2777 ic->interrupt_callback.callback = decode_interrupt_cb;
2778 ic->interrupt_callback.opaque = is;
2779 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2780 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2781 scan_all_pmts_set = 1;
2783 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2785 print_error(is->filename, err);
2789 if (scan_all_pmts_set)
2790 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2792 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2793 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2794 ret = AVERROR_OPTION_NOT_FOUND;
2800 ic->flags |= AVFMT_FLAG_GENPTS;
2802 av_format_inject_global_side_data(ic);
2804 if (find_stream_info) {
2805 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2806 int orig_nb_streams = ic->nb_streams;
2808 err = avformat_find_stream_info(ic, opts);
2810 for (i = 0; i < orig_nb_streams; i++)
2811 av_dict_free(&opts[i]);
2815 av_log(NULL, AV_LOG_WARNING,
2816 "%s: could not find codec parameters\n", is->filename);
2823 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2825 if (seek_by_bytes < 0)
2826 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2828 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2830 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2831 window_title = av_asprintf("%s - %s", t->value, input_filename);
2833 /* if seeking requested, we execute it */
2834 if (start_time != AV_NOPTS_VALUE) {
2837 timestamp = start_time;
2838 /* add the stream start time */
2839 if (ic->start_time != AV_NOPTS_VALUE)
2840 timestamp += ic->start_time;
2841 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2843 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2844 is->filename, (double)timestamp / AV_TIME_BASE);
2848 is->realtime = is_realtime(ic);
2851 av_dump_format(ic, 0, is->filename, 0);
2853 for (i = 0; i < ic->nb_streams; i++) {
2854 AVStream *st = ic->streams[i];
2855 enum AVMediaType type = st->codecpar->codec_type;
2856 st->discard = AVDISCARD_ALL;
2857 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2858 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2861 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2862 if (wanted_stream_spec[i] && st_index[i] == -1) {
2863 av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i));
2864 st_index[i] = INT_MAX;
2869 st_index[AVMEDIA_TYPE_VIDEO] =
2870 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2871 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2873 st_index[AVMEDIA_TYPE_AUDIO] =
2874 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2875 st_index[AVMEDIA_TYPE_AUDIO],
2876 st_index[AVMEDIA_TYPE_VIDEO],
2878 if (!video_disable && !subtitle_disable)
2879 st_index[AVMEDIA_TYPE_SUBTITLE] =
2880 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2881 st_index[AVMEDIA_TYPE_SUBTITLE],
2882 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2883 st_index[AVMEDIA_TYPE_AUDIO] :
2884 st_index[AVMEDIA_TYPE_VIDEO]),
2887 is->show_mode = show_mode;
2888 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2889 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2890 AVCodecParameters *codecpar = st->codecpar;
2891 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2892 if (codecpar->width)
2893 set_default_window_size(codecpar->width, codecpar->height, sar);
2896 /* open the streams */
2897 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2898 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2902 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2903 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2905 if (is->show_mode == SHOW_MODE_NONE)
2906 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2908 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2909 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2912 if (is->video_stream < 0 && is->audio_stream < 0) {
2913 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2919 if (infinite_buffer < 0 && is->realtime)
2920 infinite_buffer = 1;
2923 if (is->abort_request)
2925 if (is->paused != is->last_paused) {
2926 is->last_paused = is->paused;
2928 is->read_pause_return = av_read_pause(ic);
2932 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2934 (!strcmp(ic->iformat->name, "rtsp") ||
2935 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2936 /* wait 10 ms to avoid trying to get another packet */
2943 int64_t seek_target = is->seek_pos;
2944 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2945 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2946 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2947 // of the seek_pos/seek_rel variables
2949 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2951 av_log(NULL, AV_LOG_ERROR,
2952 "%s: error while seeking\n", is->ic->url);
2954 if (is->audio_stream >= 0) {
2955 packet_queue_flush(&is->audioq);
2956 packet_queue_put(&is->audioq, &flush_pkt);
2958 if (is->subtitle_stream >= 0) {
2959 packet_queue_flush(&is->subtitleq);
2960 packet_queue_put(&is->subtitleq, &flush_pkt);
2962 if (is->video_stream >= 0) {
2963 packet_queue_flush(&is->videoq);
2964 packet_queue_put(&is->videoq, &flush_pkt);
2966 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2967 set_clock(&is->extclk, NAN, 0);
2969 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2973 is->queue_attachments_req = 1;
2976 step_to_next_frame(is);
2978 if (is->queue_attachments_req) {
2979 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2980 AVPacket copy = { 0 };
2981 if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0)
2983 packet_queue_put(&is->videoq, ©);
2984 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2986 is->queue_attachments_req = 0;
2989 /* if the queue are full, no need to read more */
2990 if (infinite_buffer<1 &&
2991 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2992 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2993 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2994 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2996 SDL_LockMutex(wait_mutex);
2997 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2998 SDL_UnlockMutex(wait_mutex);
3002 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3003 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3004 if (loop != 1 && (!loop || --loop)) {
3005 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3006 } else if (autoexit) {
3011 ret = av_read_frame(ic, pkt);
3013 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3014 if (is->video_stream >= 0)
3015 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3016 if (is->audio_stream >= 0)
3017 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3018 if (is->subtitle_stream >= 0)
3019 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3022 if (ic->pb && ic->pb->error)
3024 SDL_LockMutex(wait_mutex);
3025 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3026 SDL_UnlockMutex(wait_mutex);
3031 /* check if packet is in play range specified by user, then queue, otherwise discard */
3032 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3033 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3034 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3035 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3036 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3037 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3038 <= ((double)duration / 1000000);
3039 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3040 packet_queue_put(&is->audioq, pkt);
3041 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3042 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3043 packet_queue_put(&is->videoq, pkt);
3044 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3045 packet_queue_put(&is->subtitleq, pkt);
3047 av_packet_unref(pkt);
3054 avformat_close_input(&ic);
3059 event.type = FF_QUIT_EVENT;
3060 event.user.data1 = is;
3061 SDL_PushEvent(&event);
3063 SDL_DestroyMutex(wait_mutex);
3067 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3071 is = av_mallocz(sizeof(VideoState));
3074 is->filename = av_strdup(filename);
3077 is->iformat = iformat;
3081 /* start video display */
3082 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3084 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3086 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3089 if (packet_queue_init(&is->videoq) < 0 ||
3090 packet_queue_init(&is->audioq) < 0 ||
3091 packet_queue_init(&is->subtitleq) < 0)
3094 if (!(is->continue_read_thread = SDL_CreateCond())) {
3095 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3099 init_clock(&is->vidclk, &is->videoq.serial);
3100 init_clock(&is->audclk, &is->audioq.serial);
3101 init_clock(&is->extclk, &is->extclk.serial);
3102 is->audio_clock_serial = -1;
3103 if (startup_volume < 0)
3104 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3105 if (startup_volume > 100)
3106 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3107 startup_volume = av_clip(startup_volume, 0, 100);
3108 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3109 is->audio_volume = startup_volume;
3111 is->av_sync_type = av_sync_type;
3112 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3113 if (!is->read_tid) {
3114 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3122 static void stream_cycle_channel(VideoState *is, int codec_type)
3124 AVFormatContext *ic = is->ic;
3125 int start_index, stream_index;
3128 AVProgram *p = NULL;
3129 int nb_streams = is->ic->nb_streams;
3131 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3132 start_index = is->last_video_stream;
3133 old_index = is->video_stream;
3134 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3135 start_index = is->last_audio_stream;
3136 old_index = is->audio_stream;
3138 start_index = is->last_subtitle_stream;
3139 old_index = is->subtitle_stream;
3141 stream_index = start_index;
3143 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3144 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3146 nb_streams = p->nb_stream_indexes;
3147 for (start_index = 0; start_index < nb_streams; start_index++)
3148 if (p->stream_index[start_index] == stream_index)
3150 if (start_index == nb_streams)
3152 stream_index = start_index;
3157 if (++stream_index >= nb_streams)
3159 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3162 is->last_subtitle_stream = -1;
3165 if (start_index == -1)
3169 if (stream_index == start_index)
3171 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3172 if (st->codecpar->codec_type == codec_type) {
3173 /* check that parameters are OK */
3174 switch (codec_type) {
3175 case AVMEDIA_TYPE_AUDIO:
3176 if (st->codecpar->sample_rate != 0 &&
3177 st->codecpar->channels != 0)
3180 case AVMEDIA_TYPE_VIDEO:
3181 case AVMEDIA_TYPE_SUBTITLE:
3189 if (p && stream_index != -1)
3190 stream_index = p->stream_index[stream_index];
3191 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3192 av_get_media_type_string(codec_type),
3196 stream_component_close(is, old_index);
3197 stream_component_open(is, stream_index);
3201 static void toggle_full_screen(VideoState *is)
3203 is_full_screen = !is_full_screen;
3204 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3207 static void toggle_audio_display(VideoState *is)
3209 int next = is->show_mode;
3211 next = (next + 1) % SHOW_MODE_NB;
3212 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3213 if (is->show_mode != next) {
3214 is->force_refresh = 1;
3215 is->show_mode = next;
3219 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3220 double remaining_time = 0.0;
3222 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3223 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3227 if (remaining_time > 0.0)
3228 av_usleep((int64_t)(remaining_time * 1000000.0));
3229 remaining_time = REFRESH_RATE;
3230 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3231 video_refresh(is, &remaining_time);
3236 static void seek_chapter(VideoState *is, int incr)
3238 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3241 if (!is->ic->nb_chapters)
3244 /* find the current chapter */
3245 for (i = 0; i < is->ic->nb_chapters; i++) {
3246 AVChapter *ch = is->ic->chapters[i];
3247 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3255 if (i >= is->ic->nb_chapters)
3258 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3259 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3260 AV_TIME_BASE_Q), 0, 0);
3263 /* handle an event sent by the GUI */
3264 static void event_loop(VideoState *cur_stream)
3267 double incr, pos, frac;
3271 refresh_loop_wait_event(cur_stream, &event);
3272 switch (event.type) {
3274 if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
3275 do_exit(cur_stream);
3278 // If we don't yet have a window, skip all key events, because read_thread might still be initializing...
3279 if (!cur_stream->width)
3281 switch (event.key.keysym.sym) {
3283 toggle_full_screen(cur_stream);
3284 cur_stream->force_refresh = 1;
3288 toggle_pause(cur_stream);
3291 toggle_mute(cur_stream);
3293 case SDLK_KP_MULTIPLY:
3295 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3297 case SDLK_KP_DIVIDE:
3299 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3301 case SDLK_s: // S: Step to next frame
3302 step_to_next_frame(cur_stream);
3305 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3308 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3311 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3312 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3313 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3316 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3320 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3321 if (++cur_stream->vfilter_idx >= nb_vfilters)
3322 cur_stream->vfilter_idx = 0;
3324 cur_stream->vfilter_idx = 0;
3325 toggle_audio_display(cur_stream);
3328 toggle_audio_display(cur_stream);
3332 if (cur_stream->ic->nb_chapters <= 1) {
3336 seek_chapter(cur_stream, 1);
3339 if (cur_stream->ic->nb_chapters <= 1) {
3343 seek_chapter(cur_stream, -1);
3357 if (seek_by_bytes) {
3359 if (pos < 0 && cur_stream->video_stream >= 0)
3360 pos = frame_queue_last_pos(&cur_stream->pictq);
3361 if (pos < 0 && cur_stream->audio_stream >= 0)
3362 pos = frame_queue_last_pos(&cur_stream->sampq);
3364 pos = avio_tell(cur_stream->ic->pb);
3365 if (cur_stream->ic->bit_rate)
3366 incr *= cur_stream->ic->bit_rate / 8.0;
3370 stream_seek(cur_stream, pos, incr, 1);
3372 pos = get_master_clock(cur_stream);
3374 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3376 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3377 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3378 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3385 case SDL_MOUSEBUTTONDOWN:
3386 if (exit_on_mousedown) {
3387 do_exit(cur_stream);
3390 if (event.button.button == SDL_BUTTON_LEFT) {
3391 static int64_t last_mouse_left_click = 0;
3392 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3393 toggle_full_screen(cur_stream);
3394 cur_stream->force_refresh = 1;
3395 last_mouse_left_click = 0;
3397 last_mouse_left_click = av_gettime_relative();
3400 case SDL_MOUSEMOTION:
3401 if (cursor_hidden) {
3405 cursor_last_shown = av_gettime_relative();
3406 if (event.type == SDL_MOUSEBUTTONDOWN) {
3407 if (event.button.button != SDL_BUTTON_RIGHT)
3411 if (!(event.motion.state & SDL_BUTTON_RMASK))
3415 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3416 uint64_t size = avio_size(cur_stream->ic->pb);
3417 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3421 int tns, thh, tmm, tss;
3422 tns = cur_stream->ic->duration / 1000000LL;
3424 tmm = (tns % 3600) / 60;
3426 frac = x / cur_stream->width;
3429 mm = (ns % 3600) / 60;
3431 av_log(NULL, AV_LOG_INFO,
3432 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3433 hh, mm, ss, thh, tmm, tss);
3434 ts = frac * cur_stream->ic->duration;
3435 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3436 ts += cur_stream->ic->start_time;
3437 stream_seek(cur_stream, ts, 0, 0);
3440 case SDL_WINDOWEVENT:
3441 switch (event.window.event) {
3442 case SDL_WINDOWEVENT_RESIZED:
3443 screen_width = cur_stream->width = event.window.data1;
3444 screen_height = cur_stream->height = event.window.data2;
3445 if (cur_stream->vis_texture) {
3446 SDL_DestroyTexture(cur_stream->vis_texture);
3447 cur_stream->vis_texture = NULL;
3449 case SDL_WINDOWEVENT_EXPOSED:
3450 cur_stream->force_refresh = 1;
3455 do_exit(cur_stream);
3463 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3465 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3466 return opt_default(NULL, "video_size", arg);
3469 static int opt_width(void *optctx, const char *opt, const char *arg)
3471 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3475 static int opt_height(void *optctx, const char *opt, const char *arg)
3477 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3481 static int opt_format(void *optctx, const char *opt, const char *arg)
3483 file_iformat = av_find_input_format(arg);
3484 if (!file_iformat) {
3485 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3486 return AVERROR(EINVAL);
3491 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3493 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3494 return opt_default(NULL, "pixel_format", arg);
3497 static int opt_sync(void *optctx, const char *opt, const char *arg)
3499 if (!strcmp(arg, "audio"))
3500 av_sync_type = AV_SYNC_AUDIO_MASTER;
3501 else if (!strcmp(arg, "video"))
3502 av_sync_type = AV_SYNC_VIDEO_MASTER;
3503 else if (!strcmp(arg, "ext"))
3504 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3506 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3512 static int opt_seek(void *optctx, const char *opt, const char *arg)
3514 start_time = parse_time_or_die(opt, arg, 1);
3518 static int opt_duration(void *optctx, const char *opt, const char *arg)
3520 duration = parse_time_or_die(opt, arg, 1);
3524 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3526 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3527 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3528 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3529 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3533 static void opt_input_file(void *optctx, const char *filename)
3535 if (input_filename) {
3536 av_log(NULL, AV_LOG_FATAL,
3537 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3538 filename, input_filename);
3541 if (!strcmp(filename, "-"))
3543 input_filename = filename;
3546 static int opt_codec(void *optctx, const char *opt, const char *arg)
3548 const char *spec = strchr(opt, ':');
3550 av_log(NULL, AV_LOG_ERROR,
3551 "No media specifier was specified in '%s' in option '%s'\n",
3553 return AVERROR(EINVAL);
3557 case 'a' : audio_codec_name = arg; break;
3558 case 's' : subtitle_codec_name = arg; break;
3559 case 'v' : video_codec_name = arg; break;
3561 av_log(NULL, AV_LOG_ERROR,
3562 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3563 return AVERROR(EINVAL);
3570 static const OptionDef options[] = {
3571 CMDUTILS_COMMON_OPTIONS
3572 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3573 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3574 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3575 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3576 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3577 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3578 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3579 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3580 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3581 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3582 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3583 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3584 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3585 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3586 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3587 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3588 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3589 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3590 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3591 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3592 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3593 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3594 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3595 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3596 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3597 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3598 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3599 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3600 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3601 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3602 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3604 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3605 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3607 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3608 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3609 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3610 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3611 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3612 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3613 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3614 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3615 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3616 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3617 "read and decode the streams to fill missing information with heuristics" },
3621 static void show_usage(void)
3623 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3624 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3625 av_log(NULL, AV_LOG_INFO, "\n");
3628 void show_help_default(const char *opt, const char *arg)
3630 av_log_set_callback(log_callback_help);
3632 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3633 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3635 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3636 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3637 #if !CONFIG_AVFILTER
3638 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3640 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3642 printf("\nWhile playing:\n"
3644 "f toggle full screen\n"
3647 "9, 0 decrease and increase volume respectively\n"
3648 "/, * decrease and increase volume respectively\n"
3649 "a cycle audio channel in the current program\n"
3650 "v cycle video channel\n"
3651 "t cycle subtitle channel in the current program\n"
3653 "w cycle video filters or show modes\n"
3654 "s activate frame-step mode\n"
3655 "left/right seek backward/forward 10 seconds\n"
3656 "down/up seek backward/forward 1 minute\n"
3657 "page down/page up seek backward/forward 10 minutes\n"
3658 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3659 "left double-click toggle full screen\n"
3663 /* Called from the main */
3664 int main(int argc, char **argv)
3671 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3672 parse_loglevel(argc, argv, options);
3674 /* register all codecs, demux and protocols */
3676 avdevice_register_all();
3678 avformat_network_init();
3682 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3683 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3685 show_banner(argc, argv, options);
3687 parse_options(NULL, argc, argv, options, opt_input_file);
3689 if (!input_filename) {
3691 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3692 av_log(NULL, AV_LOG_FATAL,
3693 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3697 if (display_disable) {
3700 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3702 flags &= ~SDL_INIT_AUDIO;
3704 /* Try to work around an occasional ALSA buffer underflow issue when the
3705 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3706 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3707 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3709 if (display_disable)
3710 flags &= ~SDL_INIT_VIDEO;
3711 if (SDL_Init (flags)) {
3712 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3713 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3717 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3718 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3720 av_init_packet(&flush_pkt);
3721 flush_pkt.data = (uint8_t *)&flush_pkt;
3723 if (!display_disable) {
3724 int flags = SDL_WINDOW_HIDDEN;
3726 flags |= SDL_WINDOW_BORDERLESS;
3728 flags |= SDL_WINDOW_RESIZABLE;
3729 window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
3730 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
3732 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
3734 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
3735 renderer = SDL_CreateRenderer(window, -1, 0);
3738 if (!SDL_GetRendererInfo(renderer, &renderer_info))
3739 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
3742 if (!window || !renderer || !renderer_info.num_texture_formats) {
3743 av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
3748 is = stream_open(input_filename, file_iformat);
3750 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");