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 (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
840 SDL_DestroyTexture(*texture);
841 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
843 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
846 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
848 memset(pixels, 0, pitch * new_height);
849 SDL_UnlockTexture(*texture);
851 av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
856 static void calculate_display_rect(SDL_Rect *rect,
857 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
858 int pic_width, int pic_height, AVRational pic_sar)
861 int width, height, x, y;
863 if (pic_sar.num == 0)
866 aspect_ratio = av_q2d(pic_sar);
868 if (aspect_ratio <= 0.0)
870 aspect_ratio *= (float)pic_width / (float)pic_height;
872 /* XXX: we suppose the screen has a 1.0 pixel ratio */
874 width = lrint(height * aspect_ratio) & ~1;
875 if (width > scr_width) {
877 height = lrint(width / aspect_ratio) & ~1;
879 x = (scr_width - width) / 2;
880 y = (scr_height - height) / 2;
881 rect->x = scr_xleft + x;
882 rect->y = scr_ytop + y;
883 rect->w = FFMAX(width, 1);
884 rect->h = FFMAX(height, 1);
887 static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
890 *sdl_blendmode = SDL_BLENDMODE_NONE;
891 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
892 if (format == AV_PIX_FMT_RGB32 ||
893 format == AV_PIX_FMT_RGB32_1 ||
894 format == AV_PIX_FMT_BGR32 ||
895 format == AV_PIX_FMT_BGR32_1)
896 *sdl_blendmode = SDL_BLENDMODE_BLEND;
897 for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
898 if (format == sdl_texture_format_map[i].format) {
899 *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
905 static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
908 SDL_BlendMode sdl_blendmode;
909 get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
910 if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
912 switch (sdl_pix_fmt) {
913 case SDL_PIXELFORMAT_UNKNOWN:
914 /* This should only happen if we are not using avfilter... */
915 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
916 frame->width, frame->height, frame->format, frame->width, frame->height,
917 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
918 if (*img_convert_ctx != NULL) {
921 if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
922 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
923 0, frame->height, pixels, pitch);
924 SDL_UnlockTexture(*tex);
927 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
931 case SDL_PIXELFORMAT_IYUV:
932 if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
933 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
934 frame->data[1], frame->linesize[1],
935 frame->data[2], frame->linesize[2]);
936 } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) {
937 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0],
938 frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
939 frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
941 av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
946 if (frame->linesize[0] < 0) {
947 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
949 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
956 static void video_image_display(VideoState *is)
962 vp = frame_queue_peek_last(&is->pictq);
963 if (is->subtitle_st) {
964 if (frame_queue_nb_remaining(&is->subpq) > 0) {
965 sp = frame_queue_peek(&is->subpq);
967 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
972 if (!sp->width || !sp->height) {
973 sp->width = vp->width;
974 sp->height = vp->height;
976 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
979 for (i = 0; i < sp->sub.num_rects; i++) {
980 AVSubtitleRect *sub_rect = sp->sub.rects[i];
982 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
983 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
984 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
985 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
987 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
988 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
989 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
990 0, NULL, NULL, NULL);
991 if (!is->sub_convert_ctx) {
992 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
995 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
996 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
997 0, sub_rect->h, pixels, pitch);
998 SDL_UnlockTexture(is->sub_texture);
1008 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1010 if (!vp->uploaded) {
1011 if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
1014 vp->flip_v = vp->frame->linesize[0] < 0;
1017 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
1019 #if USE_ONEPASS_SUBTITLE_RENDER
1020 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
1023 double xratio = (double)rect.w / (double)sp->width;
1024 double yratio = (double)rect.h / (double)sp->height;
1025 for (i = 0; i < sp->sub.num_rects; i++) {
1026 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
1027 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
1028 .y = rect.y + sub_rect->y * yratio,
1029 .w = sub_rect->w * xratio,
1030 .h = sub_rect->h * yratio};
1031 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
1037 static inline int compute_mod(int a, int b)
1039 return a < 0 ? a%b + b : a%b;
1042 static void video_audio_display(VideoState *s)
1044 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1045 int ch, channels, h, h2;
1047 int rdft_bits, nb_freq;
1049 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1051 nb_freq = 1 << (rdft_bits - 1);
1053 /* compute display index : center on currently output samples */
1054 channels = s->audio_tgt.channels;
1055 nb_display_channels = channels;
1057 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1059 delay = s->audio_write_buf_size;
1062 /* to be more precise, we take into account the time spent since
1063 the last buffer computation */
1064 if (audio_callback_time) {
1065 time_diff = av_gettime_relative() - audio_callback_time;
1066 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1069 delay += 2 * data_used;
1070 if (delay < data_used)
1073 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1074 if (s->show_mode == SHOW_MODE_WAVES) {
1076 for (i = 0; i < 1000; i += channels) {
1077 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1078 int a = s->sample_array[idx];
1079 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1080 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1081 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1083 if (h < score && (b ^ c) < 0) {
1090 s->last_i_start = i_start;
1092 i_start = s->last_i_start;
1095 if (s->show_mode == SHOW_MODE_WAVES) {
1096 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1098 /* total height for one channel */
1099 h = s->height / nb_display_channels;
1100 /* graph height / 2 */
1102 for (ch = 0; ch < nb_display_channels; ch++) {
1104 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1105 for (x = 0; x < s->width; x++) {
1106 y = (s->sample_array[i] * h2) >> 15;
1113 fill_rectangle(s->xleft + x, ys, 1, y);
1115 if (i >= SAMPLE_ARRAY_SIZE)
1116 i -= SAMPLE_ARRAY_SIZE;
1120 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1122 for (ch = 1; ch < nb_display_channels; ch++) {
1123 y = s->ytop + ch * h;
1124 fill_rectangle(s->xleft, y, s->width, 1);
1127 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1130 nb_display_channels= FFMIN(nb_display_channels, 2);
1131 if (rdft_bits != s->rdft_bits) {
1132 av_rdft_end(s->rdft);
1133 av_free(s->rdft_data);
1134 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1135 s->rdft_bits = rdft_bits;
1136 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1138 if (!s->rdft || !s->rdft_data){
1139 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1140 s->show_mode = SHOW_MODE_WAVES;
1143 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1146 for (ch = 0; ch < nb_display_channels; ch++) {
1147 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1149 for (x = 0; x < 2 * nb_freq; x++) {
1150 double w = (x-nb_freq) * (1.0 / nb_freq);
1151 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1153 if (i >= SAMPLE_ARRAY_SIZE)
1154 i -= SAMPLE_ARRAY_SIZE;
1156 av_rdft_calc(s->rdft, data[ch]);
1158 /* Least efficient way to do this, we should of course
1159 * directly access it but it is more than fast enough. */
1160 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1162 pixels += pitch * s->height;
1163 for (y = 0; y < s->height; y++) {
1164 double w = 1 / sqrt(nb_freq);
1165 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]));
1166 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1171 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1173 SDL_UnlockTexture(s->vis_texture);
1175 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1179 if (s->xpos >= s->width)
1184 static void stream_component_close(VideoState *is, int stream_index)
1186 AVFormatContext *ic = is->ic;
1187 AVCodecParameters *codecpar;
1189 if (stream_index < 0 || stream_index >= ic->nb_streams)
1191 codecpar = ic->streams[stream_index]->codecpar;
1193 switch (codecpar->codec_type) {
1194 case AVMEDIA_TYPE_AUDIO:
1195 decoder_abort(&is->auddec, &is->sampq);
1196 SDL_CloseAudioDevice(audio_dev);
1197 decoder_destroy(&is->auddec);
1198 swr_free(&is->swr_ctx);
1199 av_freep(&is->audio_buf1);
1200 is->audio_buf1_size = 0;
1201 is->audio_buf = NULL;
1204 av_rdft_end(is->rdft);
1205 av_freep(&is->rdft_data);
1210 case AVMEDIA_TYPE_VIDEO:
1211 decoder_abort(&is->viddec, &is->pictq);
1212 decoder_destroy(&is->viddec);
1214 case AVMEDIA_TYPE_SUBTITLE:
1215 decoder_abort(&is->subdec, &is->subpq);
1216 decoder_destroy(&is->subdec);
1222 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1223 switch (codecpar->codec_type) {
1224 case AVMEDIA_TYPE_AUDIO:
1225 is->audio_st = NULL;
1226 is->audio_stream = -1;
1228 case AVMEDIA_TYPE_VIDEO:
1229 is->video_st = NULL;
1230 is->video_stream = -1;
1232 case AVMEDIA_TYPE_SUBTITLE:
1233 is->subtitle_st = NULL;
1234 is->subtitle_stream = -1;
1241 static void stream_close(VideoState *is)
1243 /* XXX: use a special url_shutdown call to abort parse cleanly */
1244 is->abort_request = 1;
1245 SDL_WaitThread(is->read_tid, NULL);
1247 /* close each stream */
1248 if (is->audio_stream >= 0)
1249 stream_component_close(is, is->audio_stream);
1250 if (is->video_stream >= 0)
1251 stream_component_close(is, is->video_stream);
1252 if (is->subtitle_stream >= 0)
1253 stream_component_close(is, is->subtitle_stream);
1255 avformat_close_input(&is->ic);
1257 packet_queue_destroy(&is->videoq);
1258 packet_queue_destroy(&is->audioq);
1259 packet_queue_destroy(&is->subtitleq);
1261 /* free all pictures */
1262 frame_queue_destory(&is->pictq);
1263 frame_queue_destory(&is->sampq);
1264 frame_queue_destory(&is->subpq);
1265 SDL_DestroyCond(is->continue_read_thread);
1266 sws_freeContext(is->img_convert_ctx);
1267 sws_freeContext(is->sub_convert_ctx);
1268 av_free(is->filename);
1269 if (is->vis_texture)
1270 SDL_DestroyTexture(is->vis_texture);
1271 if (is->vid_texture)
1272 SDL_DestroyTexture(is->vid_texture);
1273 if (is->sub_texture)
1274 SDL_DestroyTexture(is->sub_texture);
1278 static void do_exit(VideoState *is)
1284 SDL_DestroyRenderer(renderer);
1286 SDL_DestroyWindow(window);
1287 av_lockmgr_register(NULL);
1290 av_freep(&vfilters_list);
1292 avformat_network_deinit();
1296 av_log(NULL, AV_LOG_QUIET, "%s", "");
1300 static void sigterm_handler(int sig)
1305 static void set_default_window_size(int width, int height, AVRational sar)
1308 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1309 default_width = rect.w;
1310 default_height = rect.h;
1313 static int video_open(VideoState *is)
1326 window_title = input_filename;
1327 SDL_SetWindowTitle(window, window_title);
1329 SDL_SetWindowSize(window, w, h);
1330 SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
1332 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1333 SDL_ShowWindow(window);
1341 /* display the current picture, if any */
1342 static void video_display(VideoState *is)
1347 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1348 SDL_RenderClear(renderer);
1349 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1350 video_audio_display(is);
1351 else if (is->video_st)
1352 video_image_display(is);
1353 SDL_RenderPresent(renderer);
1356 static double get_clock(Clock *c)
1358 if (*c->queue_serial != c->serial)
1363 double time = av_gettime_relative() / 1000000.0;
1364 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1368 static void set_clock_at(Clock *c, double pts, int serial, double time)
1371 c->last_updated = time;
1372 c->pts_drift = c->pts - time;
1376 static void set_clock(Clock *c, double pts, int serial)
1378 double time = av_gettime_relative() / 1000000.0;
1379 set_clock_at(c, pts, serial, time);
1382 static void set_clock_speed(Clock *c, double speed)
1384 set_clock(c, get_clock(c), c->serial);
1388 static void init_clock(Clock *c, int *queue_serial)
1392 c->queue_serial = queue_serial;
1393 set_clock(c, NAN, -1);
1396 static void sync_clock_to_slave(Clock *c, Clock *slave)
1398 double clock = get_clock(c);
1399 double slave_clock = get_clock(slave);
1400 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1401 set_clock(c, slave_clock, slave->serial);
1404 static int get_master_sync_type(VideoState *is) {
1405 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1407 return AV_SYNC_VIDEO_MASTER;
1409 return AV_SYNC_AUDIO_MASTER;
1410 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1412 return AV_SYNC_AUDIO_MASTER;
1414 return AV_SYNC_EXTERNAL_CLOCK;
1416 return AV_SYNC_EXTERNAL_CLOCK;
1420 /* get the current master clock value */
1421 static double get_master_clock(VideoState *is)
1425 switch (get_master_sync_type(is)) {
1426 case AV_SYNC_VIDEO_MASTER:
1427 val = get_clock(&is->vidclk);
1429 case AV_SYNC_AUDIO_MASTER:
1430 val = get_clock(&is->audclk);
1433 val = get_clock(&is->extclk);
1439 static void check_external_clock_speed(VideoState *is) {
1440 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1441 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1442 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1443 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1444 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1445 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1447 double speed = is->extclk.speed;
1449 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1453 /* seek in the stream */
1454 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1456 if (!is->seek_req) {
1459 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1461 is->seek_flags |= AVSEEK_FLAG_BYTE;
1463 SDL_CondSignal(is->continue_read_thread);
1467 /* pause or resume the video */
1468 static void stream_toggle_pause(VideoState *is)
1471 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1472 if (is->read_pause_return != AVERROR(ENOSYS)) {
1473 is->vidclk.paused = 0;
1475 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1477 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1478 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1481 static void toggle_pause(VideoState *is)
1483 stream_toggle_pause(is);
1487 static void toggle_mute(VideoState *is)
1489 is->muted = !is->muted;
1492 static void update_volume(VideoState *is, int sign, double step)
1494 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1495 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1496 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1499 static void step_to_next_frame(VideoState *is)
1501 /* if the stream is paused unpause it, then step */
1503 stream_toggle_pause(is);
1507 static double compute_target_delay(double delay, VideoState *is)
1509 double sync_threshold, diff = 0;
1511 /* update delay to follow master synchronisation source */
1512 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1513 /* if video is slave, we try to correct big delays by
1514 duplicating or deleting a frame */
1515 diff = get_clock(&is->vidclk) - get_master_clock(is);
1517 /* skip or repeat frame. We take into account the
1518 delay to compute the threshold. I still don't know
1519 if it is the best guess */
1520 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1521 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1522 if (diff <= -sync_threshold)
1523 delay = FFMAX(0, delay + diff);
1524 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1525 delay = delay + diff;
1526 else if (diff >= sync_threshold)
1531 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1537 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1538 if (vp->serial == nextvp->serial) {
1539 double duration = nextvp->pts - vp->pts;
1540 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1541 return vp->duration;
1549 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1550 /* update current video pts */
1551 set_clock(&is->vidclk, pts, serial);
1552 sync_clock_to_slave(&is->extclk, &is->vidclk);
1555 /* called to display each frame */
1556 static void video_refresh(void *opaque, double *remaining_time)
1558 VideoState *is = opaque;
1563 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1564 check_external_clock_speed(is);
1566 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1567 time = av_gettime_relative() / 1000000.0;
1568 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1570 is->last_vis_time = time;
1572 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1577 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1578 // nothing to do, no picture to display in the queue
1580 double last_duration, duration, delay;
1583 /* dequeue the picture */
1584 lastvp = frame_queue_peek_last(&is->pictq);
1585 vp = frame_queue_peek(&is->pictq);
1587 if (vp->serial != is->videoq.serial) {
1588 frame_queue_next(&is->pictq);
1592 if (lastvp->serial != vp->serial)
1593 is->frame_timer = av_gettime_relative() / 1000000.0;
1598 /* compute nominal last_duration */
1599 last_duration = vp_duration(is, lastvp, vp);
1600 delay = compute_target_delay(last_duration, is);
1602 time= av_gettime_relative()/1000000.0;
1603 if (time < is->frame_timer + delay) {
1604 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1608 is->frame_timer += delay;
1609 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1610 is->frame_timer = time;
1612 SDL_LockMutex(is->pictq.mutex);
1613 if (!isnan(vp->pts))
1614 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1615 SDL_UnlockMutex(is->pictq.mutex);
1617 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1618 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1619 duration = vp_duration(is, vp, nextvp);
1620 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1621 is->frame_drops_late++;
1622 frame_queue_next(&is->pictq);
1627 if (is->subtitle_st) {
1628 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1629 sp = frame_queue_peek(&is->subpq);
1631 if (frame_queue_nb_remaining(&is->subpq) > 1)
1632 sp2 = frame_queue_peek_next(&is->subpq);
1636 if (sp->serial != is->subtitleq.serial
1637 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1638 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1642 for (i = 0; i < sp->sub.num_rects; i++) {
1643 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1647 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1648 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1649 memset(pixels, 0, sub_rect->w << 2);
1650 SDL_UnlockTexture(is->sub_texture);
1654 frame_queue_next(&is->subpq);
1661 frame_queue_next(&is->pictq);
1662 is->force_refresh = 1;
1664 if (is->step && !is->paused)
1665 stream_toggle_pause(is);
1668 /* display picture */
1669 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1672 is->force_refresh = 0;
1674 static int64_t last_time;
1676 int aqsize, vqsize, sqsize;
1679 cur_time = av_gettime_relative();
1680 if (!last_time || (cur_time - last_time) >= 30000) {
1685 aqsize = is->audioq.size;
1687 vqsize = is->videoq.size;
1688 if (is->subtitle_st)
1689 sqsize = is->subtitleq.size;
1691 if (is->audio_st && is->video_st)
1692 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1693 else if (is->video_st)
1694 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1695 else if (is->audio_st)
1696 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1697 av_log(NULL, AV_LOG_INFO,
1698 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1699 get_master_clock(is),
1700 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1702 is->frame_drops_early + is->frame_drops_late,
1706 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1707 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1709 last_time = cur_time;
1714 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1718 #if defined(DEBUG_SYNC)
1719 printf("frame_type=%c pts=%0.3f\n",
1720 av_get_picture_type_char(src_frame->pict_type), pts);
1723 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1726 vp->sar = src_frame->sample_aspect_ratio;
1729 vp->width = src_frame->width;
1730 vp->height = src_frame->height;
1731 vp->format = src_frame->format;
1734 vp->duration = duration;
1736 vp->serial = serial;
1738 set_default_window_size(vp->width, vp->height, vp->sar);
1740 av_frame_move_ref(vp->frame, src_frame);
1741 frame_queue_push(&is->pictq);
1745 static int get_video_frame(VideoState *is, AVFrame *frame)
1749 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1755 if (frame->pts != AV_NOPTS_VALUE)
1756 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1758 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1760 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1761 if (frame->pts != AV_NOPTS_VALUE) {
1762 double diff = dpts - get_master_clock(is);
1763 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1764 diff - is->frame_last_filter_delay < 0 &&
1765 is->viddec.pkt_serial == is->vidclk.serial &&
1766 is->videoq.nb_packets) {
1767 is->frame_drops_early++;
1768 av_frame_unref(frame);
1779 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1780 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1783 int nb_filters = graph->nb_filters;
1784 AVFilterInOut *outputs = NULL, *inputs = NULL;
1787 outputs = avfilter_inout_alloc();
1788 inputs = avfilter_inout_alloc();
1789 if (!outputs || !inputs) {
1790 ret = AVERROR(ENOMEM);
1794 outputs->name = av_strdup("in");
1795 outputs->filter_ctx = source_ctx;
1796 outputs->pad_idx = 0;
1797 outputs->next = NULL;
1799 inputs->name = av_strdup("out");
1800 inputs->filter_ctx = sink_ctx;
1801 inputs->pad_idx = 0;
1802 inputs->next = NULL;
1804 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1807 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1811 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1812 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1813 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1815 ret = avfilter_graph_config(graph, NULL);
1817 avfilter_inout_free(&outputs);
1818 avfilter_inout_free(&inputs);
1822 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1824 enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
1825 char sws_flags_str[512] = "";
1826 char buffersrc_args[256];
1828 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1829 AVCodecParameters *codecpar = is->video_st->codecpar;
1830 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1831 AVDictionaryEntry *e = NULL;
1832 int nb_pix_fmts = 0;
1835 for (i = 0; i < renderer_info.num_texture_formats; i++) {
1836 for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; j++) {
1837 if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
1838 pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
1843 pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
1845 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1846 if (!strcmp(e->key, "sws_flags")) {
1847 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1849 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1851 if (strlen(sws_flags_str))
1852 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1854 graph->scale_sws_opts = av_strdup(sws_flags_str);
1856 snprintf(buffersrc_args, sizeof(buffersrc_args),
1857 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1858 frame->width, frame->height, frame->format,
1859 is->video_st->time_base.num, is->video_st->time_base.den,
1860 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1861 if (fr.num && fr.den)
1862 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1864 if ((ret = avfilter_graph_create_filter(&filt_src,
1865 avfilter_get_by_name("buffer"),
1866 "ffplay_buffer", buffersrc_args, NULL,
1870 ret = avfilter_graph_create_filter(&filt_out,
1871 avfilter_get_by_name("buffersink"),
1872 "ffplay_buffersink", NULL, NULL, graph);
1876 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1879 last_filter = filt_out;
1881 /* Note: this macro adds a filter before the lastly added filter, so the
1882 * processing order of the filters is in reverse */
1883 #define INSERT_FILT(name, arg) do { \
1884 AVFilterContext *filt_ctx; \
1886 ret = avfilter_graph_create_filter(&filt_ctx, \
1887 avfilter_get_by_name(name), \
1888 "ffplay_" name, arg, NULL, graph); \
1892 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1896 last_filter = filt_ctx; \
1900 double theta = get_rotation(is->video_st);
1902 if (fabs(theta - 90) < 1.0) {
1903 INSERT_FILT("transpose", "clock");
1904 } else if (fabs(theta - 180) < 1.0) {
1905 INSERT_FILT("hflip", NULL);
1906 INSERT_FILT("vflip", NULL);
1907 } else if (fabs(theta - 270) < 1.0) {
1908 INSERT_FILT("transpose", "cclock");
1909 } else if (fabs(theta) > 1.0) {
1910 char rotate_buf[64];
1911 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1912 INSERT_FILT("rotate", rotate_buf);
1916 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1919 is->in_video_filter = filt_src;
1920 is->out_video_filter = filt_out;
1926 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1928 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1929 int sample_rates[2] = { 0, -1 };
1930 int64_t channel_layouts[2] = { 0, -1 };
1931 int channels[2] = { 0, -1 };
1932 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1933 char aresample_swr_opts[512] = "";
1934 AVDictionaryEntry *e = NULL;
1935 char asrc_args[256];
1938 avfilter_graph_free(&is->agraph);
1939 if (!(is->agraph = avfilter_graph_alloc()))
1940 return AVERROR(ENOMEM);
1942 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1943 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1944 if (strlen(aresample_swr_opts))
1945 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1946 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1948 ret = snprintf(asrc_args, sizeof(asrc_args),
1949 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1950 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1951 is->audio_filter_src.channels,
1952 1, is->audio_filter_src.freq);
1953 if (is->audio_filter_src.channel_layout)
1954 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1955 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1957 ret = avfilter_graph_create_filter(&filt_asrc,
1958 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1959 asrc_args, NULL, is->agraph);
1964 ret = avfilter_graph_create_filter(&filt_asink,
1965 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1966 NULL, NULL, is->agraph);
1970 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1972 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1975 if (force_output_format) {
1976 channel_layouts[0] = is->audio_tgt.channel_layout;
1977 channels [0] = is->audio_tgt.channels;
1978 sample_rates [0] = is->audio_tgt.freq;
1979 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1981 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1983 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1985 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1990 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1993 is->in_audio_filter = filt_asrc;
1994 is->out_audio_filter = filt_asink;
1998 avfilter_graph_free(&is->agraph);
2001 #endif /* CONFIG_AVFILTER */
2003 static int audio_thread(void *arg)
2005 VideoState *is = arg;
2006 AVFrame *frame = av_frame_alloc();
2009 int last_serial = -1;
2010 int64_t dec_channel_layout;
2018 return AVERROR(ENOMEM);
2021 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2025 tb = (AVRational){1, frame->sample_rate};
2028 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
2031 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2032 frame->format, frame->channels) ||
2033 is->audio_filter_src.channel_layout != dec_channel_layout ||
2034 is->audio_filter_src.freq != frame->sample_rate ||
2035 is->auddec.pkt_serial != last_serial;
2038 char buf1[1024], buf2[1024];
2039 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2040 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2041 av_log(NULL, AV_LOG_DEBUG,
2042 "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",
2043 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2044 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2046 is->audio_filter_src.fmt = frame->format;
2047 is->audio_filter_src.channels = frame->channels;
2048 is->audio_filter_src.channel_layout = dec_channel_layout;
2049 is->audio_filter_src.freq = frame->sample_rate;
2050 last_serial = is->auddec.pkt_serial;
2052 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2056 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2059 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2060 tb = av_buffersink_get_time_base(is->out_audio_filter);
2062 if (!(af = frame_queue_peek_writable(&is->sampq)))
2065 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2066 af->pos = frame->pkt_pos;
2067 af->serial = is->auddec.pkt_serial;
2068 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2070 av_frame_move_ref(af->frame, frame);
2071 frame_queue_push(&is->sampq);
2074 if (is->audioq.serial != is->auddec.pkt_serial)
2077 if (ret == AVERROR_EOF)
2078 is->auddec.finished = is->auddec.pkt_serial;
2081 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2084 avfilter_graph_free(&is->agraph);
2086 av_frame_free(&frame);
2090 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2092 packet_queue_start(d->queue);
2093 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2094 if (!d->decoder_tid) {
2095 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2096 return AVERROR(ENOMEM);
2101 static int video_thread(void *arg)
2103 VideoState *is = arg;
2104 AVFrame *frame = av_frame_alloc();
2108 AVRational tb = is->video_st->time_base;
2109 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2112 AVFilterGraph *graph = avfilter_graph_alloc();
2113 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2116 enum AVPixelFormat last_format = -2;
2117 int last_serial = -1;
2118 int last_vfilter_idx = 0;
2120 av_frame_free(&frame);
2121 return AVERROR(ENOMEM);
2128 avfilter_graph_free(&graph);
2130 return AVERROR(ENOMEM);
2134 ret = get_video_frame(is, frame);
2141 if ( last_w != frame->width
2142 || last_h != frame->height
2143 || last_format != frame->format
2144 || last_serial != is->viddec.pkt_serial
2145 || last_vfilter_idx != is->vfilter_idx) {
2146 av_log(NULL, AV_LOG_DEBUG,
2147 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2149 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2150 frame->width, frame->height,
2151 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2152 avfilter_graph_free(&graph);
2153 graph = avfilter_graph_alloc();
2154 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2156 event.type = FF_QUIT_EVENT;
2157 event.user.data1 = is;
2158 SDL_PushEvent(&event);
2161 filt_in = is->in_video_filter;
2162 filt_out = is->out_video_filter;
2163 last_w = frame->width;
2164 last_h = frame->height;
2165 last_format = frame->format;
2166 last_serial = is->viddec.pkt_serial;
2167 last_vfilter_idx = is->vfilter_idx;
2168 frame_rate = av_buffersink_get_frame_rate(filt_out);
2171 ret = av_buffersrc_add_frame(filt_in, frame);
2176 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2178 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2180 if (ret == AVERROR_EOF)
2181 is->viddec.finished = is->viddec.pkt_serial;
2186 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2187 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2188 is->frame_last_filter_delay = 0;
2189 tb = av_buffersink_get_time_base(filt_out);
2191 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2192 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2193 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2194 av_frame_unref(frame);
2204 avfilter_graph_free(&graph);
2206 av_frame_free(&frame);
2210 static int subtitle_thread(void *arg)
2212 VideoState *is = arg;
2218 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2221 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2226 if (got_subtitle && sp->sub.format == 0) {
2227 if (sp->sub.pts != AV_NOPTS_VALUE)
2228 pts = sp->sub.pts / (double)AV_TIME_BASE;
2230 sp->serial = is->subdec.pkt_serial;
2231 sp->width = is->subdec.avctx->width;
2232 sp->height = is->subdec.avctx->height;
2235 /* now we can update the picture count */
2236 frame_queue_push(&is->subpq);
2237 } else if (got_subtitle) {
2238 avsubtitle_free(&sp->sub);
2244 /* copy samples for viewing in editor window */
2245 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2249 size = samples_size / sizeof(short);
2251 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2254 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2256 is->sample_array_index += len;
2257 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2258 is->sample_array_index = 0;
2263 /* return the wanted number of samples to get better sync if sync_type is video
2264 * or external master clock */
2265 static int synchronize_audio(VideoState *is, int nb_samples)
2267 int wanted_nb_samples = nb_samples;
2269 /* if not master, then we try to remove or add samples to correct the clock */
2270 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2271 double diff, avg_diff;
2272 int min_nb_samples, max_nb_samples;
2274 diff = get_clock(&is->audclk) - get_master_clock(is);
2276 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2277 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2278 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2279 /* not enough measures to have a correct estimate */
2280 is->audio_diff_avg_count++;
2282 /* estimate the A-V difference */
2283 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2285 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2286 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2287 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2288 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2289 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2291 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2292 diff, avg_diff, wanted_nb_samples - nb_samples,
2293 is->audio_clock, is->audio_diff_threshold);
2296 /* too big difference : may be initial PTS errors, so
2298 is->audio_diff_avg_count = 0;
2299 is->audio_diff_cum = 0;
2303 return wanted_nb_samples;
2307 * Decode one audio frame and return its uncompressed size.
2309 * The processed audio frame is decoded, converted if required, and
2310 * stored in is->audio_buf, with size in bytes given by the return
2313 static int audio_decode_frame(VideoState *is)
2315 int data_size, resampled_data_size;
2316 int64_t dec_channel_layout;
2317 av_unused double audio_clock0;
2318 int wanted_nb_samples;
2326 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2327 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2332 if (!(af = frame_queue_peek_readable(&is->sampq)))
2334 frame_queue_next(&is->sampq);
2335 } while (af->serial != is->audioq.serial);
2337 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2338 af->frame->nb_samples,
2339 af->frame->format, 1);
2341 dec_channel_layout =
2342 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2343 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2344 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2346 if (af->frame->format != is->audio_src.fmt ||
2347 dec_channel_layout != is->audio_src.channel_layout ||
2348 af->frame->sample_rate != is->audio_src.freq ||
2349 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2350 swr_free(&is->swr_ctx);
2351 is->swr_ctx = swr_alloc_set_opts(NULL,
2352 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2353 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2355 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2356 av_log(NULL, AV_LOG_ERROR,
2357 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2358 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2359 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2360 swr_free(&is->swr_ctx);
2363 is->audio_src.channel_layout = dec_channel_layout;
2364 is->audio_src.channels = af->frame->channels;
2365 is->audio_src.freq = af->frame->sample_rate;
2366 is->audio_src.fmt = af->frame->format;
2370 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2371 uint8_t **out = &is->audio_buf1;
2372 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2373 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2376 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2379 if (wanted_nb_samples != af->frame->nb_samples) {
2380 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2381 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2382 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2386 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2387 if (!is->audio_buf1)
2388 return AVERROR(ENOMEM);
2389 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2391 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2394 if (len2 == out_count) {
2395 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2396 if (swr_init(is->swr_ctx) < 0)
2397 swr_free(&is->swr_ctx);
2399 is->audio_buf = is->audio_buf1;
2400 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2402 is->audio_buf = af->frame->data[0];
2403 resampled_data_size = data_size;
2406 audio_clock0 = is->audio_clock;
2407 /* update the audio clock with the pts */
2408 if (!isnan(af->pts))
2409 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2411 is->audio_clock = NAN;
2412 is->audio_clock_serial = af->serial;
2415 static double last_clock;
2416 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2417 is->audio_clock - last_clock,
2418 is->audio_clock, audio_clock0);
2419 last_clock = is->audio_clock;
2422 return resampled_data_size;
2425 /* prepare a new audio buffer */
2426 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2428 VideoState *is = opaque;
2429 int audio_size, len1;
2431 audio_callback_time = av_gettime_relative();
2434 if (is->audio_buf_index >= is->audio_buf_size) {
2435 audio_size = audio_decode_frame(is);
2436 if (audio_size < 0) {
2437 /* if error, just output silence */
2438 is->audio_buf = NULL;
2439 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2441 if (is->show_mode != SHOW_MODE_VIDEO)
2442 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2443 is->audio_buf_size = audio_size;
2445 is->audio_buf_index = 0;
2447 len1 = is->audio_buf_size - is->audio_buf_index;
2450 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2451 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2453 memset(stream, 0, len1);
2454 if (!is->muted && is->audio_buf)
2455 SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
2459 is->audio_buf_index += len1;
2461 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2462 /* Let's assume the audio driver that is used by SDL has two periods. */
2463 if (!isnan(is->audio_clock)) {
2464 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);
2465 sync_clock_to_slave(&is->extclk, &is->audclk);
2469 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2471 SDL_AudioSpec wanted_spec, spec;
2473 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2474 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2475 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2477 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2479 wanted_nb_channels = atoi(env);
2480 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2482 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2483 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2484 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2486 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2487 wanted_spec.channels = wanted_nb_channels;
2488 wanted_spec.freq = wanted_sample_rate;
2489 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2490 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2493 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2494 next_sample_rate_idx--;
2495 wanted_spec.format = AUDIO_S16SYS;
2496 wanted_spec.silence = 0;
2497 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2498 wanted_spec.callback = sdl_audio_callback;
2499 wanted_spec.userdata = opaque;
2500 while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
2501 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2502 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2503 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2504 if (!wanted_spec.channels) {
2505 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2506 wanted_spec.channels = wanted_nb_channels;
2507 if (!wanted_spec.freq) {
2508 av_log(NULL, AV_LOG_ERROR,
2509 "No more combinations to try, audio open failed\n");
2513 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2515 if (spec.format != AUDIO_S16SYS) {
2516 av_log(NULL, AV_LOG_ERROR,
2517 "SDL advised audio format %d is not supported!\n", spec.format);
2520 if (spec.channels != wanted_spec.channels) {
2521 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2522 if (!wanted_channel_layout) {
2523 av_log(NULL, AV_LOG_ERROR,
2524 "SDL advised channel count %d is not supported!\n", spec.channels);
2529 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2530 audio_hw_params->freq = spec.freq;
2531 audio_hw_params->channel_layout = wanted_channel_layout;
2532 audio_hw_params->channels = spec.channels;
2533 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2534 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);
2535 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2536 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2542 /* open a given stream. Return 0 if OK */
2543 static int stream_component_open(VideoState *is, int stream_index)
2545 AVFormatContext *ic = is->ic;
2546 AVCodecContext *avctx;
2548 const char *forced_codec_name = NULL;
2549 AVDictionary *opts = NULL;
2550 AVDictionaryEntry *t = NULL;
2551 int sample_rate, nb_channels;
2552 int64_t channel_layout;
2554 int stream_lowres = lowres;
2556 if (stream_index < 0 || stream_index >= ic->nb_streams)
2559 avctx = avcodec_alloc_context3(NULL);
2561 return AVERROR(ENOMEM);
2563 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2566 avctx->pkt_timebase = ic->streams[stream_index]->time_base;
2568 codec = avcodec_find_decoder(avctx->codec_id);
2570 switch(avctx->codec_type){
2571 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2572 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2573 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2575 if (forced_codec_name)
2576 codec = avcodec_find_decoder_by_name(forced_codec_name);
2578 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2579 "No codec could be found with name '%s'\n", forced_codec_name);
2580 else av_log(NULL, AV_LOG_WARNING,
2581 "No codec could be found with id %d\n", avctx->codec_id);
2582 ret = AVERROR(EINVAL);
2586 avctx->codec_id = codec->id;
2587 if (stream_lowres > codec->max_lowres) {
2588 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2590 stream_lowres = codec->max_lowres;
2592 avctx->lowres = stream_lowres;
2595 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2597 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2598 if (!av_dict_get(opts, "threads", NULL, 0))
2599 av_dict_set(&opts, "threads", "auto", 0);
2601 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2602 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2603 av_dict_set(&opts, "refcounted_frames", "1", 0);
2604 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2607 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2608 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2609 ret = AVERROR_OPTION_NOT_FOUND;
2614 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2615 switch (avctx->codec_type) {
2616 case AVMEDIA_TYPE_AUDIO:
2619 AVFilterContext *sink;
2621 is->audio_filter_src.freq = avctx->sample_rate;
2622 is->audio_filter_src.channels = avctx->channels;
2623 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2624 is->audio_filter_src.fmt = avctx->sample_fmt;
2625 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2627 sink = is->out_audio_filter;
2628 sample_rate = av_buffersink_get_sample_rate(sink);
2629 nb_channels = av_buffersink_get_channels(sink);
2630 channel_layout = av_buffersink_get_channel_layout(sink);
2633 sample_rate = avctx->sample_rate;
2634 nb_channels = avctx->channels;
2635 channel_layout = avctx->channel_layout;
2638 /* prepare audio output */
2639 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2641 is->audio_hw_buf_size = ret;
2642 is->audio_src = is->audio_tgt;
2643 is->audio_buf_size = 0;
2644 is->audio_buf_index = 0;
2646 /* init averaging filter */
2647 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2648 is->audio_diff_avg_count = 0;
2649 /* since we do not have a precise anough audio FIFO fullness,
2650 we correct audio sync only if larger than this threshold */
2651 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2653 is->audio_stream = stream_index;
2654 is->audio_st = ic->streams[stream_index];
2656 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2657 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2658 is->auddec.start_pts = is->audio_st->start_time;
2659 is->auddec.start_pts_tb = is->audio_st->time_base;
2661 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2663 SDL_PauseAudioDevice(audio_dev, 0);
2665 case AVMEDIA_TYPE_VIDEO:
2666 is->video_stream = stream_index;
2667 is->video_st = ic->streams[stream_index];
2669 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2670 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2672 is->queue_attachments_req = 1;
2674 case AVMEDIA_TYPE_SUBTITLE:
2675 is->subtitle_stream = stream_index;
2676 is->subtitle_st = ic->streams[stream_index];
2678 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2679 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2688 avcodec_free_context(&avctx);
2690 av_dict_free(&opts);
2695 static int decode_interrupt_cb(void *ctx)
2697 VideoState *is = ctx;
2698 return is->abort_request;
2701 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2702 return stream_id < 0 ||
2703 queue->abort_request ||
2704 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2705 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2708 static int is_realtime(AVFormatContext *s)
2710 if( !strcmp(s->iformat->name, "rtp")
2711 || !strcmp(s->iformat->name, "rtsp")
2712 || !strcmp(s->iformat->name, "sdp")
2716 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2717 || !strncmp(s->filename, "udp:", 4)
2724 /* this thread gets the stream from the disk or the network */
2725 static int read_thread(void *arg)
2727 VideoState *is = arg;
2728 AVFormatContext *ic = NULL;
2730 int st_index[AVMEDIA_TYPE_NB];
2731 AVPacket pkt1, *pkt = &pkt1;
2732 int64_t stream_start_time;
2733 int pkt_in_play_range = 0;
2734 AVDictionaryEntry *t;
2735 SDL_mutex *wait_mutex = SDL_CreateMutex();
2736 int scan_all_pmts_set = 0;
2740 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2741 ret = AVERROR(ENOMEM);
2745 memset(st_index, -1, sizeof(st_index));
2746 is->last_video_stream = is->video_stream = -1;
2747 is->last_audio_stream = is->audio_stream = -1;
2748 is->last_subtitle_stream = is->subtitle_stream = -1;
2751 ic = avformat_alloc_context();
2753 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2754 ret = AVERROR(ENOMEM);
2757 ic->interrupt_callback.callback = decode_interrupt_cb;
2758 ic->interrupt_callback.opaque = is;
2759 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2760 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2761 scan_all_pmts_set = 1;
2763 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2765 print_error(is->filename, err);
2769 if (scan_all_pmts_set)
2770 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2772 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2773 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2774 ret = AVERROR_OPTION_NOT_FOUND;
2780 ic->flags |= AVFMT_FLAG_GENPTS;
2782 av_format_inject_global_side_data(ic);
2784 if (find_stream_info) {
2785 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2786 int orig_nb_streams = ic->nb_streams;
2788 err = avformat_find_stream_info(ic, opts);
2790 for (i = 0; i < orig_nb_streams; i++)
2791 av_dict_free(&opts[i]);
2795 av_log(NULL, AV_LOG_WARNING,
2796 "%s: could not find codec parameters\n", is->filename);
2803 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2805 if (seek_by_bytes < 0)
2806 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2808 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2810 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2811 window_title = av_asprintf("%s - %s", t->value, input_filename);
2813 /* if seeking requested, we execute it */
2814 if (start_time != AV_NOPTS_VALUE) {
2817 timestamp = start_time;
2818 /* add the stream start time */
2819 if (ic->start_time != AV_NOPTS_VALUE)
2820 timestamp += ic->start_time;
2821 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2823 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2824 is->filename, (double)timestamp / AV_TIME_BASE);
2828 is->realtime = is_realtime(ic);
2831 av_dump_format(ic, 0, is->filename, 0);
2833 for (i = 0; i < ic->nb_streams; i++) {
2834 AVStream *st = ic->streams[i];
2835 enum AVMediaType type = st->codecpar->codec_type;
2836 st->discard = AVDISCARD_ALL;
2837 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2838 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2841 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2842 if (wanted_stream_spec[i] && st_index[i] == -1) {
2843 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));
2844 st_index[i] = INT_MAX;
2849 st_index[AVMEDIA_TYPE_VIDEO] =
2850 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2851 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2853 st_index[AVMEDIA_TYPE_AUDIO] =
2854 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2855 st_index[AVMEDIA_TYPE_AUDIO],
2856 st_index[AVMEDIA_TYPE_VIDEO],
2858 if (!video_disable && !subtitle_disable)
2859 st_index[AVMEDIA_TYPE_SUBTITLE] =
2860 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2861 st_index[AVMEDIA_TYPE_SUBTITLE],
2862 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2863 st_index[AVMEDIA_TYPE_AUDIO] :
2864 st_index[AVMEDIA_TYPE_VIDEO]),
2867 is->show_mode = show_mode;
2868 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2869 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2870 AVCodecParameters *codecpar = st->codecpar;
2871 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2872 if (codecpar->width)
2873 set_default_window_size(codecpar->width, codecpar->height, sar);
2876 /* open the streams */
2877 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2878 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2882 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2883 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2885 if (is->show_mode == SHOW_MODE_NONE)
2886 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2888 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2889 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2892 if (is->video_stream < 0 && is->audio_stream < 0) {
2893 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2899 if (infinite_buffer < 0 && is->realtime)
2900 infinite_buffer = 1;
2903 if (is->abort_request)
2905 if (is->paused != is->last_paused) {
2906 is->last_paused = is->paused;
2908 is->read_pause_return = av_read_pause(ic);
2912 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2914 (!strcmp(ic->iformat->name, "rtsp") ||
2915 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2916 /* wait 10 ms to avoid trying to get another packet */
2923 int64_t seek_target = is->seek_pos;
2924 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2925 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2926 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2927 // of the seek_pos/seek_rel variables
2929 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2931 av_log(NULL, AV_LOG_ERROR,
2932 "%s: error while seeking\n", is->ic->filename);
2934 if (is->audio_stream >= 0) {
2935 packet_queue_flush(&is->audioq);
2936 packet_queue_put(&is->audioq, &flush_pkt);
2938 if (is->subtitle_stream >= 0) {
2939 packet_queue_flush(&is->subtitleq);
2940 packet_queue_put(&is->subtitleq, &flush_pkt);
2942 if (is->video_stream >= 0) {
2943 packet_queue_flush(&is->videoq);
2944 packet_queue_put(&is->videoq, &flush_pkt);
2946 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2947 set_clock(&is->extclk, NAN, 0);
2949 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2953 is->queue_attachments_req = 1;
2956 step_to_next_frame(is);
2958 if (is->queue_attachments_req) {
2959 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2960 AVPacket copy = { 0 };
2961 if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0)
2963 packet_queue_put(&is->videoq, ©);
2964 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2966 is->queue_attachments_req = 0;
2969 /* if the queue are full, no need to read more */
2970 if (infinite_buffer<1 &&
2971 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2972 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2973 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2974 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2976 SDL_LockMutex(wait_mutex);
2977 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2978 SDL_UnlockMutex(wait_mutex);
2982 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2983 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2984 if (loop != 1 && (!loop || --loop)) {
2985 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2986 } else if (autoexit) {
2991 ret = av_read_frame(ic, pkt);
2993 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
2994 if (is->video_stream >= 0)
2995 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2996 if (is->audio_stream >= 0)
2997 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2998 if (is->subtitle_stream >= 0)
2999 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3002 if (ic->pb && ic->pb->error)
3004 SDL_LockMutex(wait_mutex);
3005 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3006 SDL_UnlockMutex(wait_mutex);
3011 /* check if packet is in play range specified by user, then queue, otherwise discard */
3012 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3013 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3014 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3015 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3016 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3017 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3018 <= ((double)duration / 1000000);
3019 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3020 packet_queue_put(&is->audioq, pkt);
3021 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3022 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3023 packet_queue_put(&is->videoq, pkt);
3024 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3025 packet_queue_put(&is->subtitleq, pkt);
3027 av_packet_unref(pkt);
3034 avformat_close_input(&ic);
3039 event.type = FF_QUIT_EVENT;
3040 event.user.data1 = is;
3041 SDL_PushEvent(&event);
3043 SDL_DestroyMutex(wait_mutex);
3047 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3051 is = av_mallocz(sizeof(VideoState));
3054 is->filename = av_strdup(filename);
3057 is->iformat = iformat;
3061 /* start video display */
3062 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3064 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3066 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3069 if (packet_queue_init(&is->videoq) < 0 ||
3070 packet_queue_init(&is->audioq) < 0 ||
3071 packet_queue_init(&is->subtitleq) < 0)
3074 if (!(is->continue_read_thread = SDL_CreateCond())) {
3075 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3079 init_clock(&is->vidclk, &is->videoq.serial);
3080 init_clock(&is->audclk, &is->audioq.serial);
3081 init_clock(&is->extclk, &is->extclk.serial);
3082 is->audio_clock_serial = -1;
3083 if (startup_volume < 0)
3084 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3085 if (startup_volume > 100)
3086 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3087 startup_volume = av_clip(startup_volume, 0, 100);
3088 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3089 is->audio_volume = startup_volume;
3091 is->av_sync_type = av_sync_type;
3092 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3093 if (!is->read_tid) {
3094 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3102 static void stream_cycle_channel(VideoState *is, int codec_type)
3104 AVFormatContext *ic = is->ic;
3105 int start_index, stream_index;
3108 AVProgram *p = NULL;
3109 int nb_streams = is->ic->nb_streams;
3111 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3112 start_index = is->last_video_stream;
3113 old_index = is->video_stream;
3114 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3115 start_index = is->last_audio_stream;
3116 old_index = is->audio_stream;
3118 start_index = is->last_subtitle_stream;
3119 old_index = is->subtitle_stream;
3121 stream_index = start_index;
3123 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3124 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3126 nb_streams = p->nb_stream_indexes;
3127 for (start_index = 0; start_index < nb_streams; start_index++)
3128 if (p->stream_index[start_index] == stream_index)
3130 if (start_index == nb_streams)
3132 stream_index = start_index;
3137 if (++stream_index >= nb_streams)
3139 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3142 is->last_subtitle_stream = -1;
3145 if (start_index == -1)
3149 if (stream_index == start_index)
3151 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3152 if (st->codecpar->codec_type == codec_type) {
3153 /* check that parameters are OK */
3154 switch (codec_type) {
3155 case AVMEDIA_TYPE_AUDIO:
3156 if (st->codecpar->sample_rate != 0 &&
3157 st->codecpar->channels != 0)
3160 case AVMEDIA_TYPE_VIDEO:
3161 case AVMEDIA_TYPE_SUBTITLE:
3169 if (p && stream_index != -1)
3170 stream_index = p->stream_index[stream_index];
3171 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3172 av_get_media_type_string(codec_type),
3176 stream_component_close(is, old_index);
3177 stream_component_open(is, stream_index);
3181 static void toggle_full_screen(VideoState *is)
3183 is_full_screen = !is_full_screen;
3184 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3187 static void toggle_audio_display(VideoState *is)
3189 int next = is->show_mode;
3191 next = (next + 1) % SHOW_MODE_NB;
3192 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3193 if (is->show_mode != next) {
3194 is->force_refresh = 1;
3195 is->show_mode = next;
3199 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3200 double remaining_time = 0.0;
3202 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3203 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3207 if (remaining_time > 0.0)
3208 av_usleep((int64_t)(remaining_time * 1000000.0));
3209 remaining_time = REFRESH_RATE;
3210 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3211 video_refresh(is, &remaining_time);
3216 static void seek_chapter(VideoState *is, int incr)
3218 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3221 if (!is->ic->nb_chapters)
3224 /* find the current chapter */
3225 for (i = 0; i < is->ic->nb_chapters; i++) {
3226 AVChapter *ch = is->ic->chapters[i];
3227 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3235 if (i >= is->ic->nb_chapters)
3238 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3239 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3240 AV_TIME_BASE_Q), 0, 0);
3243 /* handle an event sent by the GUI */
3244 static void event_loop(VideoState *cur_stream)
3247 double incr, pos, frac;
3251 refresh_loop_wait_event(cur_stream, &event);
3252 switch (event.type) {
3254 if (exit_on_keydown) {
3255 do_exit(cur_stream);
3258 switch (event.key.keysym.sym) {
3261 do_exit(cur_stream);
3264 toggle_full_screen(cur_stream);
3265 cur_stream->force_refresh = 1;
3269 toggle_pause(cur_stream);
3272 toggle_mute(cur_stream);
3274 case SDLK_KP_MULTIPLY:
3276 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3278 case SDLK_KP_DIVIDE:
3280 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3282 case SDLK_s: // S: Step to next frame
3283 step_to_next_frame(cur_stream);
3286 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3289 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3292 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3293 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3294 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3297 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3301 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3302 if (++cur_stream->vfilter_idx >= nb_vfilters)
3303 cur_stream->vfilter_idx = 0;
3305 cur_stream->vfilter_idx = 0;
3306 toggle_audio_display(cur_stream);
3309 toggle_audio_display(cur_stream);
3313 if (cur_stream->ic->nb_chapters <= 1) {
3317 seek_chapter(cur_stream, 1);
3320 if (cur_stream->ic->nb_chapters <= 1) {
3324 seek_chapter(cur_stream, -1);
3338 if (seek_by_bytes) {
3340 if (pos < 0 && cur_stream->video_stream >= 0)
3341 pos = frame_queue_last_pos(&cur_stream->pictq);
3342 if (pos < 0 && cur_stream->audio_stream >= 0)
3343 pos = frame_queue_last_pos(&cur_stream->sampq);
3345 pos = avio_tell(cur_stream->ic->pb);
3346 if (cur_stream->ic->bit_rate)
3347 incr *= cur_stream->ic->bit_rate / 8.0;
3351 stream_seek(cur_stream, pos, incr, 1);
3353 pos = get_master_clock(cur_stream);
3355 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3357 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3358 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3359 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3366 case SDL_MOUSEBUTTONDOWN:
3367 if (exit_on_mousedown) {
3368 do_exit(cur_stream);
3371 if (event.button.button == SDL_BUTTON_LEFT) {
3372 static int64_t last_mouse_left_click = 0;
3373 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3374 toggle_full_screen(cur_stream);
3375 cur_stream->force_refresh = 1;
3376 last_mouse_left_click = 0;
3378 last_mouse_left_click = av_gettime_relative();
3381 case SDL_MOUSEMOTION:
3382 if (cursor_hidden) {
3386 cursor_last_shown = av_gettime_relative();
3387 if (event.type == SDL_MOUSEBUTTONDOWN) {
3388 if (event.button.button != SDL_BUTTON_RIGHT)
3392 if (!(event.motion.state & SDL_BUTTON_RMASK))
3396 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3397 uint64_t size = avio_size(cur_stream->ic->pb);
3398 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3402 int tns, thh, tmm, tss;
3403 tns = cur_stream->ic->duration / 1000000LL;
3405 tmm = (tns % 3600) / 60;
3407 frac = x / cur_stream->width;
3410 mm = (ns % 3600) / 60;
3412 av_log(NULL, AV_LOG_INFO,
3413 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3414 hh, mm, ss, thh, tmm, tss);
3415 ts = frac * cur_stream->ic->duration;
3416 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3417 ts += cur_stream->ic->start_time;
3418 stream_seek(cur_stream, ts, 0, 0);
3421 case SDL_WINDOWEVENT:
3422 switch (event.window.event) {
3423 case SDL_WINDOWEVENT_RESIZED:
3424 screen_width = cur_stream->width = event.window.data1;
3425 screen_height = cur_stream->height = event.window.data2;
3426 if (cur_stream->vis_texture) {
3427 SDL_DestroyTexture(cur_stream->vis_texture);
3428 cur_stream->vis_texture = NULL;
3430 case SDL_WINDOWEVENT_EXPOSED:
3431 cur_stream->force_refresh = 1;
3436 do_exit(cur_stream);
3444 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3446 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3447 return opt_default(NULL, "video_size", arg);
3450 static int opt_width(void *optctx, const char *opt, const char *arg)
3452 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3456 static int opt_height(void *optctx, const char *opt, const char *arg)
3458 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3462 static int opt_format(void *optctx, const char *opt, const char *arg)
3464 file_iformat = av_find_input_format(arg);
3465 if (!file_iformat) {
3466 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3467 return AVERROR(EINVAL);
3472 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3474 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3475 return opt_default(NULL, "pixel_format", arg);
3478 static int opt_sync(void *optctx, const char *opt, const char *arg)
3480 if (!strcmp(arg, "audio"))
3481 av_sync_type = AV_SYNC_AUDIO_MASTER;
3482 else if (!strcmp(arg, "video"))
3483 av_sync_type = AV_SYNC_VIDEO_MASTER;
3484 else if (!strcmp(arg, "ext"))
3485 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3487 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3493 static int opt_seek(void *optctx, const char *opt, const char *arg)
3495 start_time = parse_time_or_die(opt, arg, 1);
3499 static int opt_duration(void *optctx, const char *opt, const char *arg)
3501 duration = parse_time_or_die(opt, arg, 1);
3505 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3507 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3508 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3509 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3510 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3514 static void opt_input_file(void *optctx, const char *filename)
3516 if (input_filename) {
3517 av_log(NULL, AV_LOG_FATAL,
3518 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3519 filename, input_filename);
3522 if (!strcmp(filename, "-"))
3524 input_filename = filename;
3527 static int opt_codec(void *optctx, const char *opt, const char *arg)
3529 const char *spec = strchr(opt, ':');
3531 av_log(NULL, AV_LOG_ERROR,
3532 "No media specifier was specified in '%s' in option '%s'\n",
3534 return AVERROR(EINVAL);
3538 case 'a' : audio_codec_name = arg; break;
3539 case 's' : subtitle_codec_name = arg; break;
3540 case 'v' : video_codec_name = arg; break;
3542 av_log(NULL, AV_LOG_ERROR,
3543 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3544 return AVERROR(EINVAL);
3551 static const OptionDef options[] = {
3552 CMDUTILS_COMMON_OPTIONS
3553 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3554 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3555 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3556 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3557 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3558 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3559 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3560 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3561 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3562 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3563 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3564 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3565 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3566 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3567 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3568 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3569 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3570 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3571 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3572 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3573 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3574 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3575 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3576 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3577 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3578 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3579 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3580 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3581 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3582 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3583 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3585 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3586 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3588 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3589 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3590 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3591 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3592 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3593 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3594 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3595 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3596 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3597 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3598 "read and decode the streams to fill missing information with heuristics" },
3602 static void show_usage(void)
3604 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3605 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3606 av_log(NULL, AV_LOG_INFO, "\n");
3609 void show_help_default(const char *opt, const char *arg)
3611 av_log_set_callback(log_callback_help);
3613 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3614 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3616 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3617 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3618 #if !CONFIG_AVFILTER
3619 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3621 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3623 printf("\nWhile playing:\n"
3625 "f toggle full screen\n"
3628 "9, 0 decrease and increase volume respectively\n"
3629 "/, * decrease and increase volume respectively\n"
3630 "a cycle audio channel in the current program\n"
3631 "v cycle video channel\n"
3632 "t cycle subtitle channel in the current program\n"
3634 "w cycle video filters or show modes\n"
3635 "s activate frame-step mode\n"
3636 "left/right seek backward/forward 10 seconds\n"
3637 "down/up seek backward/forward 1 minute\n"
3638 "page down/page up seek backward/forward 10 minutes\n"
3639 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3640 "left double-click toggle full screen\n"
3644 static int lockmgr(void **mtx, enum AVLockOp op)
3647 case AV_LOCK_CREATE:
3648 *mtx = SDL_CreateMutex();
3650 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3654 case AV_LOCK_OBTAIN:
3655 return !!SDL_LockMutex(*mtx);
3656 case AV_LOCK_RELEASE:
3657 return !!SDL_UnlockMutex(*mtx);
3658 case AV_LOCK_DESTROY:
3659 SDL_DestroyMutex(*mtx);
3665 /* Called from the main */
3666 int main(int argc, char **argv)
3673 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3674 parse_loglevel(argc, argv, options);
3676 /* register all codecs, demux and protocols */
3678 avdevice_register_all();
3681 avfilter_register_all();
3684 avformat_network_init();
3688 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3689 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3691 show_banner(argc, argv, options);
3693 parse_options(NULL, argc, argv, options, opt_input_file);
3695 if (!input_filename) {
3697 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3698 av_log(NULL, AV_LOG_FATAL,
3699 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3703 if (display_disable) {
3706 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3708 flags &= ~SDL_INIT_AUDIO;
3710 /* Try to work around an occasional ALSA buffer underflow issue when the
3711 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3712 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3713 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3715 if (display_disable)
3716 flags &= ~SDL_INIT_VIDEO;
3717 if (SDL_Init (flags)) {
3718 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3719 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3723 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3724 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3726 if (av_lockmgr_register(lockmgr)) {
3727 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3731 av_init_packet(&flush_pkt);
3732 flush_pkt.data = (uint8_t *)&flush_pkt;
3734 if (!display_disable) {
3735 int flags = SDL_WINDOW_HIDDEN;
3737 flags |= SDL_WINDOW_BORDERLESS;
3739 flags |= SDL_WINDOW_RESIZABLE;
3740 window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
3741 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
3743 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
3745 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
3746 renderer = SDL_CreateRenderer(window, -1, 0);
3749 if (!SDL_GetRendererInfo(renderer, &renderer_info))
3750 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
3753 if (!window || !renderer || !renderer_info.num_texture_formats) {
3754 av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
3759 is = stream_open(input_filename, file_iformat);
3761 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");