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;
365 static const struct TextureFormatEntry {
366 enum AVPixelFormat format;
368 } sdl_texture_format_map[] = {
369 { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 },
370 { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 },
371 { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 },
372 { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 },
373 { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 },
374 { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 },
375 { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 },
376 { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 },
377 { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 },
378 { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 },
379 { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 },
380 { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 },
381 { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 },
382 { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 },
383 { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 },
384 { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 },
385 { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV },
386 { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 },
387 { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY },
388 { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN },
392 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
394 GROW_ARRAY(vfilters_list, nb_vfilters);
395 vfilters_list[nb_vfilters - 1] = arg;
401 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
402 enum AVSampleFormat fmt2, int64_t channel_count2)
404 /* If channel count == 1, planar and non-planar formats are the same */
405 if (channel_count1 == 1 && channel_count2 == 1)
406 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
408 return channel_count1 != channel_count2 || fmt1 != fmt2;
412 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
414 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
415 return channel_layout;
420 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
422 MyAVPacketList *pkt1;
424 if (q->abort_request)
427 pkt1 = av_malloc(sizeof(MyAVPacketList));
432 if (pkt == &flush_pkt)
434 pkt1->serial = q->serial;
439 q->last_pkt->next = pkt1;
442 q->size += pkt1->pkt.size + sizeof(*pkt1);
443 q->duration += pkt1->pkt.duration;
444 /* XXX: should duplicate packet data in DV case */
445 SDL_CondSignal(q->cond);
449 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
453 SDL_LockMutex(q->mutex);
454 ret = packet_queue_put_private(q, pkt);
455 SDL_UnlockMutex(q->mutex);
457 if (pkt != &flush_pkt && ret < 0)
458 av_packet_unref(pkt);
463 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
465 AVPacket pkt1, *pkt = &pkt1;
469 pkt->stream_index = stream_index;
470 return packet_queue_put(q, pkt);
473 /* packet queue handling */
474 static int packet_queue_init(PacketQueue *q)
476 memset(q, 0, sizeof(PacketQueue));
477 q->mutex = SDL_CreateMutex();
479 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
480 return AVERROR(ENOMEM);
482 q->cond = SDL_CreateCond();
484 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
485 return AVERROR(ENOMEM);
487 q->abort_request = 1;
491 static void packet_queue_flush(PacketQueue *q)
493 MyAVPacketList *pkt, *pkt1;
495 SDL_LockMutex(q->mutex);
496 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
498 av_packet_unref(&pkt->pkt);
506 SDL_UnlockMutex(q->mutex);
509 static void packet_queue_destroy(PacketQueue *q)
511 packet_queue_flush(q);
512 SDL_DestroyMutex(q->mutex);
513 SDL_DestroyCond(q->cond);
516 static void packet_queue_abort(PacketQueue *q)
518 SDL_LockMutex(q->mutex);
520 q->abort_request = 1;
522 SDL_CondSignal(q->cond);
524 SDL_UnlockMutex(q->mutex);
527 static void packet_queue_start(PacketQueue *q)
529 SDL_LockMutex(q->mutex);
530 q->abort_request = 0;
531 packet_queue_put_private(q, &flush_pkt);
532 SDL_UnlockMutex(q->mutex);
535 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
536 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
538 MyAVPacketList *pkt1;
541 SDL_LockMutex(q->mutex);
544 if (q->abort_request) {
551 q->first_pkt = pkt1->next;
555 q->size -= pkt1->pkt.size + sizeof(*pkt1);
556 q->duration -= pkt1->pkt.duration;
559 *serial = pkt1->serial;
567 SDL_CondWait(q->cond, q->mutex);
570 SDL_UnlockMutex(q->mutex);
574 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
575 memset(d, 0, sizeof(Decoder));
578 d->empty_queue_cond = empty_queue_cond;
579 d->start_pts = AV_NOPTS_VALUE;
583 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
584 int ret = AVERROR(EAGAIN);
589 if (d->queue->serial == d->pkt_serial) {
591 if (d->queue->abort_request)
594 switch (d->avctx->codec_type) {
595 case AVMEDIA_TYPE_VIDEO:
596 ret = avcodec_receive_frame(d->avctx, frame);
598 if (decoder_reorder_pts == -1) {
599 frame->pts = frame->best_effort_timestamp;
600 } else if (!decoder_reorder_pts) {
601 frame->pts = frame->pkt_dts;
605 case AVMEDIA_TYPE_AUDIO:
606 ret = avcodec_receive_frame(d->avctx, frame);
608 AVRational tb = (AVRational){1, frame->sample_rate};
609 if (frame->pts != AV_NOPTS_VALUE)
610 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
611 else if (d->next_pts != AV_NOPTS_VALUE)
612 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
613 if (frame->pts != AV_NOPTS_VALUE) {
614 d->next_pts = frame->pts + frame->nb_samples;
620 if (ret == AVERROR_EOF) {
621 d->finished = d->pkt_serial;
622 avcodec_flush_buffers(d->avctx);
627 } while (ret != AVERROR(EAGAIN));
631 if (d->queue->nb_packets == 0)
632 SDL_CondSignal(d->empty_queue_cond);
633 if (d->packet_pending) {
634 av_packet_move_ref(&pkt, &d->pkt);
635 d->packet_pending = 0;
637 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
640 } while (d->queue->serial != d->pkt_serial);
642 if (pkt.data == flush_pkt.data) {
643 avcodec_flush_buffers(d->avctx);
645 d->next_pts = d->start_pts;
646 d->next_pts_tb = d->start_pts_tb;
648 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
650 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
652 ret = AVERROR(EAGAIN);
654 if (got_frame && !pkt.data) {
655 d->packet_pending = 1;
656 av_packet_move_ref(&d->pkt, &pkt);
658 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
661 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
662 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
663 d->packet_pending = 1;
664 av_packet_move_ref(&d->pkt, &pkt);
667 av_packet_unref(&pkt);
672 static void decoder_destroy(Decoder *d) {
673 av_packet_unref(&d->pkt);
674 avcodec_free_context(&d->avctx);
677 static void frame_queue_unref_item(Frame *vp)
679 av_frame_unref(vp->frame);
680 avsubtitle_free(&vp->sub);
683 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
686 memset(f, 0, sizeof(FrameQueue));
687 if (!(f->mutex = SDL_CreateMutex())) {
688 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
689 return AVERROR(ENOMEM);
691 if (!(f->cond = SDL_CreateCond())) {
692 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
693 return AVERROR(ENOMEM);
696 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
697 f->keep_last = !!keep_last;
698 for (i = 0; i < f->max_size; i++)
699 if (!(f->queue[i].frame = av_frame_alloc()))
700 return AVERROR(ENOMEM);
704 static void frame_queue_destory(FrameQueue *f)
707 for (i = 0; i < f->max_size; i++) {
708 Frame *vp = &f->queue[i];
709 frame_queue_unref_item(vp);
710 av_frame_free(&vp->frame);
712 SDL_DestroyMutex(f->mutex);
713 SDL_DestroyCond(f->cond);
716 static void frame_queue_signal(FrameQueue *f)
718 SDL_LockMutex(f->mutex);
719 SDL_CondSignal(f->cond);
720 SDL_UnlockMutex(f->mutex);
723 static Frame *frame_queue_peek(FrameQueue *f)
725 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
728 static Frame *frame_queue_peek_next(FrameQueue *f)
730 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
733 static Frame *frame_queue_peek_last(FrameQueue *f)
735 return &f->queue[f->rindex];
738 static Frame *frame_queue_peek_writable(FrameQueue *f)
740 /* wait until we have space to put a new frame */
741 SDL_LockMutex(f->mutex);
742 while (f->size >= f->max_size &&
743 !f->pktq->abort_request) {
744 SDL_CondWait(f->cond, f->mutex);
746 SDL_UnlockMutex(f->mutex);
748 if (f->pktq->abort_request)
751 return &f->queue[f->windex];
754 static Frame *frame_queue_peek_readable(FrameQueue *f)
756 /* wait until we have a readable a new frame */
757 SDL_LockMutex(f->mutex);
758 while (f->size - f->rindex_shown <= 0 &&
759 !f->pktq->abort_request) {
760 SDL_CondWait(f->cond, f->mutex);
762 SDL_UnlockMutex(f->mutex);
764 if (f->pktq->abort_request)
767 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
770 static void frame_queue_push(FrameQueue *f)
772 if (++f->windex == f->max_size)
774 SDL_LockMutex(f->mutex);
776 SDL_CondSignal(f->cond);
777 SDL_UnlockMutex(f->mutex);
780 static void frame_queue_next(FrameQueue *f)
782 if (f->keep_last && !f->rindex_shown) {
786 frame_queue_unref_item(&f->queue[f->rindex]);
787 if (++f->rindex == f->max_size)
789 SDL_LockMutex(f->mutex);
791 SDL_CondSignal(f->cond);
792 SDL_UnlockMutex(f->mutex);
795 /* return the number of undisplayed frames in the queue */
796 static int frame_queue_nb_remaining(FrameQueue *f)
798 return f->size - f->rindex_shown;
801 /* return last shown position */
802 static int64_t frame_queue_last_pos(FrameQueue *f)
804 Frame *fp = &f->queue[f->rindex];
805 if (f->rindex_shown && fp->serial == f->pktq->serial)
811 static void decoder_abort(Decoder *d, FrameQueue *fq)
813 packet_queue_abort(d->queue);
814 frame_queue_signal(fq);
815 SDL_WaitThread(d->decoder_tid, NULL);
816 d->decoder_tid = NULL;
817 packet_queue_flush(d->queue);
820 static inline void fill_rectangle(int x, int y, int w, int h)
828 SDL_RenderFillRect(renderer, &rect);
831 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
835 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
838 SDL_DestroyTexture(*texture);
839 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
841 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
844 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
846 memset(pixels, 0, pitch * new_height);
847 SDL_UnlockTexture(*texture);
849 av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
854 static void calculate_display_rect(SDL_Rect *rect,
855 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
856 int pic_width, int pic_height, AVRational pic_sar)
859 int width, height, x, y;
861 if (pic_sar.num == 0)
864 aspect_ratio = av_q2d(pic_sar);
866 if (aspect_ratio <= 0.0)
868 aspect_ratio *= (float)pic_width / (float)pic_height;
870 /* XXX: we suppose the screen has a 1.0 pixel ratio */
872 width = lrint(height * aspect_ratio) & ~1;
873 if (width > scr_width) {
875 height = lrint(width / aspect_ratio) & ~1;
877 x = (scr_width - width) / 2;
878 y = (scr_height - height) / 2;
879 rect->x = scr_xleft + x;
880 rect->y = scr_ytop + y;
881 rect->w = FFMAX(width, 1);
882 rect->h = FFMAX(height, 1);
885 static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
888 *sdl_blendmode = SDL_BLENDMODE_NONE;
889 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
890 if (format == AV_PIX_FMT_RGB32 ||
891 format == AV_PIX_FMT_RGB32_1 ||
892 format == AV_PIX_FMT_BGR32 ||
893 format == AV_PIX_FMT_BGR32_1)
894 *sdl_blendmode = SDL_BLENDMODE_BLEND;
895 for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
896 if (format == sdl_texture_format_map[i].format) {
897 *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
903 static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
906 SDL_BlendMode sdl_blendmode;
907 get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
908 if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
910 switch (sdl_pix_fmt) {
911 case SDL_PIXELFORMAT_UNKNOWN:
912 /* This should only happen if we are not using avfilter... */
913 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
914 frame->width, frame->height, frame->format, frame->width, frame->height,
915 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
916 if (*img_convert_ctx != NULL) {
919 if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
920 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
921 0, frame->height, pixels, pitch);
922 SDL_UnlockTexture(*tex);
925 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
929 case SDL_PIXELFORMAT_IYUV:
930 if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
931 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
932 frame->data[1], frame->linesize[1],
933 frame->data[2], frame->linesize[2]);
934 } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) {
935 ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0],
936 frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
937 frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
939 av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
944 if (frame->linesize[0] < 0) {
945 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
947 ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
954 static void video_image_display(VideoState *is)
960 vp = frame_queue_peek_last(&is->pictq);
961 if (is->subtitle_st) {
962 if (frame_queue_nb_remaining(&is->subpq) > 0) {
963 sp = frame_queue_peek(&is->subpq);
965 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
970 if (!sp->width || !sp->height) {
971 sp->width = vp->width;
972 sp->height = vp->height;
974 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
977 for (i = 0; i < sp->sub.num_rects; i++) {
978 AVSubtitleRect *sub_rect = sp->sub.rects[i];
980 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
981 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
982 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
983 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
985 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
986 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
987 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
988 0, NULL, NULL, NULL);
989 if (!is->sub_convert_ctx) {
990 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
993 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
994 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
995 0, sub_rect->h, pixels, pitch);
996 SDL_UnlockTexture(is->sub_texture);
1006 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1008 if (!vp->uploaded) {
1009 if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
1012 vp->flip_v = vp->frame->linesize[0] < 0;
1015 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
1017 #if USE_ONEPASS_SUBTITLE_RENDER
1018 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
1021 double xratio = (double)rect.w / (double)sp->width;
1022 double yratio = (double)rect.h / (double)sp->height;
1023 for (i = 0; i < sp->sub.num_rects; i++) {
1024 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
1025 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
1026 .y = rect.y + sub_rect->y * yratio,
1027 .w = sub_rect->w * xratio,
1028 .h = sub_rect->h * yratio};
1029 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
1035 static inline int compute_mod(int a, int b)
1037 return a < 0 ? a%b + b : a%b;
1040 static void video_audio_display(VideoState *s)
1042 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1043 int ch, channels, h, h2;
1045 int rdft_bits, nb_freq;
1047 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1049 nb_freq = 1 << (rdft_bits - 1);
1051 /* compute display index : center on currently output samples */
1052 channels = s->audio_tgt.channels;
1053 nb_display_channels = channels;
1055 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1057 delay = s->audio_write_buf_size;
1060 /* to be more precise, we take into account the time spent since
1061 the last buffer computation */
1062 if (audio_callback_time) {
1063 time_diff = av_gettime_relative() - audio_callback_time;
1064 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1067 delay += 2 * data_used;
1068 if (delay < data_used)
1071 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1072 if (s->show_mode == SHOW_MODE_WAVES) {
1074 for (i = 0; i < 1000; i += channels) {
1075 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1076 int a = s->sample_array[idx];
1077 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1078 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1079 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1081 if (h < score && (b ^ c) < 0) {
1088 s->last_i_start = i_start;
1090 i_start = s->last_i_start;
1093 if (s->show_mode == SHOW_MODE_WAVES) {
1094 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1096 /* total height for one channel */
1097 h = s->height / nb_display_channels;
1098 /* graph height / 2 */
1100 for (ch = 0; ch < nb_display_channels; ch++) {
1102 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1103 for (x = 0; x < s->width; x++) {
1104 y = (s->sample_array[i] * h2) >> 15;
1111 fill_rectangle(s->xleft + x, ys, 1, y);
1113 if (i >= SAMPLE_ARRAY_SIZE)
1114 i -= SAMPLE_ARRAY_SIZE;
1118 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1120 for (ch = 1; ch < nb_display_channels; ch++) {
1121 y = s->ytop + ch * h;
1122 fill_rectangle(s->xleft, y, s->width, 1);
1125 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1128 nb_display_channels= FFMIN(nb_display_channels, 2);
1129 if (rdft_bits != s->rdft_bits) {
1130 av_rdft_end(s->rdft);
1131 av_free(s->rdft_data);
1132 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1133 s->rdft_bits = rdft_bits;
1134 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1136 if (!s->rdft || !s->rdft_data){
1137 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1138 s->show_mode = SHOW_MODE_WAVES;
1141 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1144 for (ch = 0; ch < nb_display_channels; ch++) {
1145 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1147 for (x = 0; x < 2 * nb_freq; x++) {
1148 double w = (x-nb_freq) * (1.0 / nb_freq);
1149 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1151 if (i >= SAMPLE_ARRAY_SIZE)
1152 i -= SAMPLE_ARRAY_SIZE;
1154 av_rdft_calc(s->rdft, data[ch]);
1156 /* Least efficient way to do this, we should of course
1157 * directly access it but it is more than fast enough. */
1158 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1160 pixels += pitch * s->height;
1161 for (y = 0; y < s->height; y++) {
1162 double w = 1 / sqrt(nb_freq);
1163 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]));
1164 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1169 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1171 SDL_UnlockTexture(s->vis_texture);
1173 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1177 if (s->xpos >= s->width)
1182 static void stream_component_close(VideoState *is, int stream_index)
1184 AVFormatContext *ic = is->ic;
1185 AVCodecParameters *codecpar;
1187 if (stream_index < 0 || stream_index >= ic->nb_streams)
1189 codecpar = ic->streams[stream_index]->codecpar;
1191 switch (codecpar->codec_type) {
1192 case AVMEDIA_TYPE_AUDIO:
1193 decoder_abort(&is->auddec, &is->sampq);
1195 decoder_destroy(&is->auddec);
1196 swr_free(&is->swr_ctx);
1197 av_freep(&is->audio_buf1);
1198 is->audio_buf1_size = 0;
1199 is->audio_buf = NULL;
1202 av_rdft_end(is->rdft);
1203 av_freep(&is->rdft_data);
1208 case AVMEDIA_TYPE_VIDEO:
1209 decoder_abort(&is->viddec, &is->pictq);
1210 decoder_destroy(&is->viddec);
1212 case AVMEDIA_TYPE_SUBTITLE:
1213 decoder_abort(&is->subdec, &is->subpq);
1214 decoder_destroy(&is->subdec);
1220 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1221 switch (codecpar->codec_type) {
1222 case AVMEDIA_TYPE_AUDIO:
1223 is->audio_st = NULL;
1224 is->audio_stream = -1;
1226 case AVMEDIA_TYPE_VIDEO:
1227 is->video_st = NULL;
1228 is->video_stream = -1;
1230 case AVMEDIA_TYPE_SUBTITLE:
1231 is->subtitle_st = NULL;
1232 is->subtitle_stream = -1;
1239 static void stream_close(VideoState *is)
1241 /* XXX: use a special url_shutdown call to abort parse cleanly */
1242 is->abort_request = 1;
1243 SDL_WaitThread(is->read_tid, NULL);
1245 /* close each stream */
1246 if (is->audio_stream >= 0)
1247 stream_component_close(is, is->audio_stream);
1248 if (is->video_stream >= 0)
1249 stream_component_close(is, is->video_stream);
1250 if (is->subtitle_stream >= 0)
1251 stream_component_close(is, is->subtitle_stream);
1253 avformat_close_input(&is->ic);
1255 packet_queue_destroy(&is->videoq);
1256 packet_queue_destroy(&is->audioq);
1257 packet_queue_destroy(&is->subtitleq);
1259 /* free all pictures */
1260 frame_queue_destory(&is->pictq);
1261 frame_queue_destory(&is->sampq);
1262 frame_queue_destory(&is->subpq);
1263 SDL_DestroyCond(is->continue_read_thread);
1264 sws_freeContext(is->img_convert_ctx);
1265 sws_freeContext(is->sub_convert_ctx);
1266 av_free(is->filename);
1267 if (is->vis_texture)
1268 SDL_DestroyTexture(is->vis_texture);
1269 if (is->vid_texture)
1270 SDL_DestroyTexture(is->vid_texture);
1271 if (is->sub_texture)
1272 SDL_DestroyTexture(is->sub_texture);
1276 static void do_exit(VideoState *is)
1282 SDL_DestroyRenderer(renderer);
1284 SDL_DestroyWindow(window);
1285 av_lockmgr_register(NULL);
1288 av_freep(&vfilters_list);
1290 avformat_network_deinit();
1294 av_log(NULL, AV_LOG_QUIET, "%s", "");
1298 static void sigterm_handler(int sig)
1303 static void set_default_window_size(int width, int height, AVRational sar)
1306 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1307 default_width = rect.w;
1308 default_height = rect.h;
1311 static int video_open(VideoState *is)
1324 int flags = SDL_WINDOW_SHOWN;
1326 window_title = input_filename;
1328 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1330 flags |= SDL_WINDOW_BORDERLESS;
1332 flags |= SDL_WINDOW_RESIZABLE;
1333 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1334 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1336 SDL_RendererInfo info;
1337 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1339 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1340 renderer = SDL_CreateRenderer(window, -1, 0);
1343 if (!SDL_GetRendererInfo(renderer, &info))
1344 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1348 SDL_SetWindowSize(window, w, h);
1351 if (!window || !renderer) {
1352 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1362 /* display the current picture, if any */
1363 static void video_display(VideoState *is)
1368 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1369 SDL_RenderClear(renderer);
1370 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1371 video_audio_display(is);
1372 else if (is->video_st)
1373 video_image_display(is);
1374 SDL_RenderPresent(renderer);
1377 static double get_clock(Clock *c)
1379 if (*c->queue_serial != c->serial)
1384 double time = av_gettime_relative() / 1000000.0;
1385 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1389 static void set_clock_at(Clock *c, double pts, int serial, double time)
1392 c->last_updated = time;
1393 c->pts_drift = c->pts - time;
1397 static void set_clock(Clock *c, double pts, int serial)
1399 double time = av_gettime_relative() / 1000000.0;
1400 set_clock_at(c, pts, serial, time);
1403 static void set_clock_speed(Clock *c, double speed)
1405 set_clock(c, get_clock(c), c->serial);
1409 static void init_clock(Clock *c, int *queue_serial)
1413 c->queue_serial = queue_serial;
1414 set_clock(c, NAN, -1);
1417 static void sync_clock_to_slave(Clock *c, Clock *slave)
1419 double clock = get_clock(c);
1420 double slave_clock = get_clock(slave);
1421 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1422 set_clock(c, slave_clock, slave->serial);
1425 static int get_master_sync_type(VideoState *is) {
1426 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1428 return AV_SYNC_VIDEO_MASTER;
1430 return AV_SYNC_AUDIO_MASTER;
1431 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1433 return AV_SYNC_AUDIO_MASTER;
1435 return AV_SYNC_EXTERNAL_CLOCK;
1437 return AV_SYNC_EXTERNAL_CLOCK;
1441 /* get the current master clock value */
1442 static double get_master_clock(VideoState *is)
1446 switch (get_master_sync_type(is)) {
1447 case AV_SYNC_VIDEO_MASTER:
1448 val = get_clock(&is->vidclk);
1450 case AV_SYNC_AUDIO_MASTER:
1451 val = get_clock(&is->audclk);
1454 val = get_clock(&is->extclk);
1460 static void check_external_clock_speed(VideoState *is) {
1461 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1462 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1463 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1464 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1465 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1466 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1468 double speed = is->extclk.speed;
1470 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1474 /* seek in the stream */
1475 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1477 if (!is->seek_req) {
1480 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1482 is->seek_flags |= AVSEEK_FLAG_BYTE;
1484 SDL_CondSignal(is->continue_read_thread);
1488 /* pause or resume the video */
1489 static void stream_toggle_pause(VideoState *is)
1492 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1493 if (is->read_pause_return != AVERROR(ENOSYS)) {
1494 is->vidclk.paused = 0;
1496 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1498 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1499 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1502 static void toggle_pause(VideoState *is)
1504 stream_toggle_pause(is);
1508 static void toggle_mute(VideoState *is)
1510 is->muted = !is->muted;
1513 static void update_volume(VideoState *is, int sign, double step)
1515 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1516 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1517 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1520 static void step_to_next_frame(VideoState *is)
1522 /* if the stream is paused unpause it, then step */
1524 stream_toggle_pause(is);
1528 static double compute_target_delay(double delay, VideoState *is)
1530 double sync_threshold, diff = 0;
1532 /* update delay to follow master synchronisation source */
1533 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1534 /* if video is slave, we try to correct big delays by
1535 duplicating or deleting a frame */
1536 diff = get_clock(&is->vidclk) - get_master_clock(is);
1538 /* skip or repeat frame. We take into account the
1539 delay to compute the threshold. I still don't know
1540 if it is the best guess */
1541 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1542 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1543 if (diff <= -sync_threshold)
1544 delay = FFMAX(0, delay + diff);
1545 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1546 delay = delay + diff;
1547 else if (diff >= sync_threshold)
1552 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1558 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1559 if (vp->serial == nextvp->serial) {
1560 double duration = nextvp->pts - vp->pts;
1561 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1562 return vp->duration;
1570 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1571 /* update current video pts */
1572 set_clock(&is->vidclk, pts, serial);
1573 sync_clock_to_slave(&is->extclk, &is->vidclk);
1576 /* called to display each frame */
1577 static void video_refresh(void *opaque, double *remaining_time)
1579 VideoState *is = opaque;
1584 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1585 check_external_clock_speed(is);
1587 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1588 time = av_gettime_relative() / 1000000.0;
1589 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1591 is->last_vis_time = time;
1593 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1598 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1599 // nothing to do, no picture to display in the queue
1601 double last_duration, duration, delay;
1604 /* dequeue the picture */
1605 lastvp = frame_queue_peek_last(&is->pictq);
1606 vp = frame_queue_peek(&is->pictq);
1608 if (vp->serial != is->videoq.serial) {
1609 frame_queue_next(&is->pictq);
1613 if (lastvp->serial != vp->serial)
1614 is->frame_timer = av_gettime_relative() / 1000000.0;
1619 /* compute nominal last_duration */
1620 last_duration = vp_duration(is, lastvp, vp);
1621 delay = compute_target_delay(last_duration, is);
1623 time= av_gettime_relative()/1000000.0;
1624 if (time < is->frame_timer + delay) {
1625 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1629 is->frame_timer += delay;
1630 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1631 is->frame_timer = time;
1633 SDL_LockMutex(is->pictq.mutex);
1634 if (!isnan(vp->pts))
1635 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1636 SDL_UnlockMutex(is->pictq.mutex);
1638 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1639 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1640 duration = vp_duration(is, vp, nextvp);
1641 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1642 is->frame_drops_late++;
1643 frame_queue_next(&is->pictq);
1648 if (is->subtitle_st) {
1649 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1650 sp = frame_queue_peek(&is->subpq);
1652 if (frame_queue_nb_remaining(&is->subpq) > 1)
1653 sp2 = frame_queue_peek_next(&is->subpq);
1657 if (sp->serial != is->subtitleq.serial
1658 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1659 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1663 for (i = 0; i < sp->sub.num_rects; i++) {
1664 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1668 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1669 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1670 memset(pixels, 0, sub_rect->w << 2);
1671 SDL_UnlockTexture(is->sub_texture);
1675 frame_queue_next(&is->subpq);
1682 frame_queue_next(&is->pictq);
1683 is->force_refresh = 1;
1685 if (is->step && !is->paused)
1686 stream_toggle_pause(is);
1689 /* display picture */
1690 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1693 is->force_refresh = 0;
1695 static int64_t last_time;
1697 int aqsize, vqsize, sqsize;
1700 cur_time = av_gettime_relative();
1701 if (!last_time || (cur_time - last_time) >= 30000) {
1706 aqsize = is->audioq.size;
1708 vqsize = is->videoq.size;
1709 if (is->subtitle_st)
1710 sqsize = is->subtitleq.size;
1712 if (is->audio_st && is->video_st)
1713 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1714 else if (is->video_st)
1715 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1716 else if (is->audio_st)
1717 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1718 av_log(NULL, AV_LOG_INFO,
1719 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1720 get_master_clock(is),
1721 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1723 is->frame_drops_early + is->frame_drops_late,
1727 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1728 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1730 last_time = cur_time;
1735 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1739 #if defined(DEBUG_SYNC)
1740 printf("frame_type=%c pts=%0.3f\n",
1741 av_get_picture_type_char(src_frame->pict_type), pts);
1744 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1747 vp->sar = src_frame->sample_aspect_ratio;
1750 vp->width = src_frame->width;
1751 vp->height = src_frame->height;
1752 vp->format = src_frame->format;
1755 vp->duration = duration;
1757 vp->serial = serial;
1759 set_default_window_size(vp->width, vp->height, vp->sar);
1761 av_frame_move_ref(vp->frame, src_frame);
1762 frame_queue_push(&is->pictq);
1766 static int get_video_frame(VideoState *is, AVFrame *frame)
1770 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1776 if (frame->pts != AV_NOPTS_VALUE)
1777 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1779 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1781 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1782 if (frame->pts != AV_NOPTS_VALUE) {
1783 double diff = dpts - get_master_clock(is);
1784 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1785 diff - is->frame_last_filter_delay < 0 &&
1786 is->viddec.pkt_serial == is->vidclk.serial &&
1787 is->videoq.nb_packets) {
1788 is->frame_drops_early++;
1789 av_frame_unref(frame);
1800 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1801 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1804 int nb_filters = graph->nb_filters;
1805 AVFilterInOut *outputs = NULL, *inputs = NULL;
1808 outputs = avfilter_inout_alloc();
1809 inputs = avfilter_inout_alloc();
1810 if (!outputs || !inputs) {
1811 ret = AVERROR(ENOMEM);
1815 outputs->name = av_strdup("in");
1816 outputs->filter_ctx = source_ctx;
1817 outputs->pad_idx = 0;
1818 outputs->next = NULL;
1820 inputs->name = av_strdup("out");
1821 inputs->filter_ctx = sink_ctx;
1822 inputs->pad_idx = 0;
1823 inputs->next = NULL;
1825 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1828 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1832 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1833 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1834 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1836 ret = avfilter_graph_config(graph, NULL);
1838 avfilter_inout_free(&outputs);
1839 avfilter_inout_free(&inputs);
1843 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1845 enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
1846 char sws_flags_str[512] = "";
1847 char buffersrc_args[256];
1849 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1850 AVCodecParameters *codecpar = is->video_st->codecpar;
1851 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1852 AVDictionaryEntry *e = NULL;
1855 for (i = 0; i < FF_ARRAY_ELEMS(pix_fmts); i++)
1856 pix_fmts[i] = sdl_texture_format_map[i].format;
1858 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1859 if (!strcmp(e->key, "sws_flags")) {
1860 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1862 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1864 if (strlen(sws_flags_str))
1865 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1867 graph->scale_sws_opts = av_strdup(sws_flags_str);
1869 snprintf(buffersrc_args, sizeof(buffersrc_args),
1870 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1871 frame->width, frame->height, frame->format,
1872 is->video_st->time_base.num, is->video_st->time_base.den,
1873 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1874 if (fr.num && fr.den)
1875 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1877 if ((ret = avfilter_graph_create_filter(&filt_src,
1878 avfilter_get_by_name("buffer"),
1879 "ffplay_buffer", buffersrc_args, NULL,
1883 ret = avfilter_graph_create_filter(&filt_out,
1884 avfilter_get_by_name("buffersink"),
1885 "ffplay_buffersink", NULL, NULL, graph);
1889 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1892 last_filter = filt_out;
1894 /* Note: this macro adds a filter before the lastly added filter, so the
1895 * processing order of the filters is in reverse */
1896 #define INSERT_FILT(name, arg) do { \
1897 AVFilterContext *filt_ctx; \
1899 ret = avfilter_graph_create_filter(&filt_ctx, \
1900 avfilter_get_by_name(name), \
1901 "ffplay_" name, arg, NULL, graph); \
1905 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1909 last_filter = filt_ctx; \
1913 double theta = get_rotation(is->video_st);
1915 if (fabs(theta - 90) < 1.0) {
1916 INSERT_FILT("transpose", "clock");
1917 } else if (fabs(theta - 180) < 1.0) {
1918 INSERT_FILT("hflip", NULL);
1919 INSERT_FILT("vflip", NULL);
1920 } else if (fabs(theta - 270) < 1.0) {
1921 INSERT_FILT("transpose", "cclock");
1922 } else if (fabs(theta) > 1.0) {
1923 char rotate_buf[64];
1924 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1925 INSERT_FILT("rotate", rotate_buf);
1929 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1932 is->in_video_filter = filt_src;
1933 is->out_video_filter = filt_out;
1939 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1941 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1942 int sample_rates[2] = { 0, -1 };
1943 int64_t channel_layouts[2] = { 0, -1 };
1944 int channels[2] = { 0, -1 };
1945 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1946 char aresample_swr_opts[512] = "";
1947 AVDictionaryEntry *e = NULL;
1948 char asrc_args[256];
1951 avfilter_graph_free(&is->agraph);
1952 if (!(is->agraph = avfilter_graph_alloc()))
1953 return AVERROR(ENOMEM);
1955 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1956 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1957 if (strlen(aresample_swr_opts))
1958 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1959 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1961 ret = snprintf(asrc_args, sizeof(asrc_args),
1962 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1963 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1964 is->audio_filter_src.channels,
1965 1, is->audio_filter_src.freq);
1966 if (is->audio_filter_src.channel_layout)
1967 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1968 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1970 ret = avfilter_graph_create_filter(&filt_asrc,
1971 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1972 asrc_args, NULL, is->agraph);
1977 ret = avfilter_graph_create_filter(&filt_asink,
1978 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1979 NULL, NULL, is->agraph);
1983 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1985 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1988 if (force_output_format) {
1989 channel_layouts[0] = is->audio_tgt.channel_layout;
1990 channels [0] = is->audio_tgt.channels;
1991 sample_rates [0] = is->audio_tgt.freq;
1992 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1994 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1996 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1998 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2003 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2006 is->in_audio_filter = filt_asrc;
2007 is->out_audio_filter = filt_asink;
2011 avfilter_graph_free(&is->agraph);
2014 #endif /* CONFIG_AVFILTER */
2016 static int audio_thread(void *arg)
2018 VideoState *is = arg;
2019 AVFrame *frame = av_frame_alloc();
2022 int last_serial = -1;
2023 int64_t dec_channel_layout;
2031 return AVERROR(ENOMEM);
2034 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2038 tb = (AVRational){1, frame->sample_rate};
2041 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
2044 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2045 frame->format, frame->channels) ||
2046 is->audio_filter_src.channel_layout != dec_channel_layout ||
2047 is->audio_filter_src.freq != frame->sample_rate ||
2048 is->auddec.pkt_serial != last_serial;
2051 char buf1[1024], buf2[1024];
2052 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2053 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2054 av_log(NULL, AV_LOG_DEBUG,
2055 "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",
2056 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2057 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2059 is->audio_filter_src.fmt = frame->format;
2060 is->audio_filter_src.channels = frame->channels;
2061 is->audio_filter_src.channel_layout = dec_channel_layout;
2062 is->audio_filter_src.freq = frame->sample_rate;
2063 last_serial = is->auddec.pkt_serial;
2065 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2069 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2072 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2073 tb = av_buffersink_get_time_base(is->out_audio_filter);
2075 if (!(af = frame_queue_peek_writable(&is->sampq)))
2078 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2079 af->pos = frame->pkt_pos;
2080 af->serial = is->auddec.pkt_serial;
2081 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2083 av_frame_move_ref(af->frame, frame);
2084 frame_queue_push(&is->sampq);
2087 if (is->audioq.serial != is->auddec.pkt_serial)
2090 if (ret == AVERROR_EOF)
2091 is->auddec.finished = is->auddec.pkt_serial;
2094 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2097 avfilter_graph_free(&is->agraph);
2099 av_frame_free(&frame);
2103 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2105 packet_queue_start(d->queue);
2106 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2107 if (!d->decoder_tid) {
2108 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2109 return AVERROR(ENOMEM);
2114 static int video_thread(void *arg)
2116 VideoState *is = arg;
2117 AVFrame *frame = av_frame_alloc();
2121 AVRational tb = is->video_st->time_base;
2122 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2125 AVFilterGraph *graph = avfilter_graph_alloc();
2126 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2129 enum AVPixelFormat last_format = -2;
2130 int last_serial = -1;
2131 int last_vfilter_idx = 0;
2133 av_frame_free(&frame);
2134 return AVERROR(ENOMEM);
2141 avfilter_graph_free(&graph);
2143 return AVERROR(ENOMEM);
2147 ret = get_video_frame(is, frame);
2154 if ( last_w != frame->width
2155 || last_h != frame->height
2156 || last_format != frame->format
2157 || last_serial != is->viddec.pkt_serial
2158 || last_vfilter_idx != is->vfilter_idx) {
2159 av_log(NULL, AV_LOG_DEBUG,
2160 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2162 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2163 frame->width, frame->height,
2164 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2165 avfilter_graph_free(&graph);
2166 graph = avfilter_graph_alloc();
2167 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2169 event.type = FF_QUIT_EVENT;
2170 event.user.data1 = is;
2171 SDL_PushEvent(&event);
2174 filt_in = is->in_video_filter;
2175 filt_out = is->out_video_filter;
2176 last_w = frame->width;
2177 last_h = frame->height;
2178 last_format = frame->format;
2179 last_serial = is->viddec.pkt_serial;
2180 last_vfilter_idx = is->vfilter_idx;
2181 frame_rate = av_buffersink_get_frame_rate(filt_out);
2184 ret = av_buffersrc_add_frame(filt_in, frame);
2189 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2191 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2193 if (ret == AVERROR_EOF)
2194 is->viddec.finished = is->viddec.pkt_serial;
2199 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2200 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2201 is->frame_last_filter_delay = 0;
2202 tb = av_buffersink_get_time_base(filt_out);
2204 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2205 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2206 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2207 av_frame_unref(frame);
2217 avfilter_graph_free(&graph);
2219 av_frame_free(&frame);
2223 static int subtitle_thread(void *arg)
2225 VideoState *is = arg;
2231 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2234 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2239 if (got_subtitle && sp->sub.format == 0) {
2240 if (sp->sub.pts != AV_NOPTS_VALUE)
2241 pts = sp->sub.pts / (double)AV_TIME_BASE;
2243 sp->serial = is->subdec.pkt_serial;
2244 sp->width = is->subdec.avctx->width;
2245 sp->height = is->subdec.avctx->height;
2248 /* now we can update the picture count */
2249 frame_queue_push(&is->subpq);
2250 } else if (got_subtitle) {
2251 avsubtitle_free(&sp->sub);
2257 /* copy samples for viewing in editor window */
2258 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2262 size = samples_size / sizeof(short);
2264 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2267 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2269 is->sample_array_index += len;
2270 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2271 is->sample_array_index = 0;
2276 /* return the wanted number of samples to get better sync if sync_type is video
2277 * or external master clock */
2278 static int synchronize_audio(VideoState *is, int nb_samples)
2280 int wanted_nb_samples = nb_samples;
2282 /* if not master, then we try to remove or add samples to correct the clock */
2283 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2284 double diff, avg_diff;
2285 int min_nb_samples, max_nb_samples;
2287 diff = get_clock(&is->audclk) - get_master_clock(is);
2289 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2290 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2291 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2292 /* not enough measures to have a correct estimate */
2293 is->audio_diff_avg_count++;
2295 /* estimate the A-V difference */
2296 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2298 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2299 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2300 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2301 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2302 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2304 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2305 diff, avg_diff, wanted_nb_samples - nb_samples,
2306 is->audio_clock, is->audio_diff_threshold);
2309 /* too big difference : may be initial PTS errors, so
2311 is->audio_diff_avg_count = 0;
2312 is->audio_diff_cum = 0;
2316 return wanted_nb_samples;
2320 * Decode one audio frame and return its uncompressed size.
2322 * The processed audio frame is decoded, converted if required, and
2323 * stored in is->audio_buf, with size in bytes given by the return
2326 static int audio_decode_frame(VideoState *is)
2328 int data_size, resampled_data_size;
2329 int64_t dec_channel_layout;
2330 av_unused double audio_clock0;
2331 int wanted_nb_samples;
2339 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2340 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2345 if (!(af = frame_queue_peek_readable(&is->sampq)))
2347 frame_queue_next(&is->sampq);
2348 } while (af->serial != is->audioq.serial);
2350 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2351 af->frame->nb_samples,
2352 af->frame->format, 1);
2354 dec_channel_layout =
2355 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2356 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2357 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2359 if (af->frame->format != is->audio_src.fmt ||
2360 dec_channel_layout != is->audio_src.channel_layout ||
2361 af->frame->sample_rate != is->audio_src.freq ||
2362 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2363 swr_free(&is->swr_ctx);
2364 is->swr_ctx = swr_alloc_set_opts(NULL,
2365 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2366 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2368 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2369 av_log(NULL, AV_LOG_ERROR,
2370 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2371 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2372 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2373 swr_free(&is->swr_ctx);
2376 is->audio_src.channel_layout = dec_channel_layout;
2377 is->audio_src.channels = af->frame->channels;
2378 is->audio_src.freq = af->frame->sample_rate;
2379 is->audio_src.fmt = af->frame->format;
2383 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2384 uint8_t **out = &is->audio_buf1;
2385 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2386 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2389 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2392 if (wanted_nb_samples != af->frame->nb_samples) {
2393 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2394 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2395 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2399 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2400 if (!is->audio_buf1)
2401 return AVERROR(ENOMEM);
2402 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2404 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2407 if (len2 == out_count) {
2408 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2409 if (swr_init(is->swr_ctx) < 0)
2410 swr_free(&is->swr_ctx);
2412 is->audio_buf = is->audio_buf1;
2413 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2415 is->audio_buf = af->frame->data[0];
2416 resampled_data_size = data_size;
2419 audio_clock0 = is->audio_clock;
2420 /* update the audio clock with the pts */
2421 if (!isnan(af->pts))
2422 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2424 is->audio_clock = NAN;
2425 is->audio_clock_serial = af->serial;
2428 static double last_clock;
2429 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2430 is->audio_clock - last_clock,
2431 is->audio_clock, audio_clock0);
2432 last_clock = is->audio_clock;
2435 return resampled_data_size;
2438 /* prepare a new audio buffer */
2439 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2441 VideoState *is = opaque;
2442 int audio_size, len1;
2444 audio_callback_time = av_gettime_relative();
2447 if (is->audio_buf_index >= is->audio_buf_size) {
2448 audio_size = audio_decode_frame(is);
2449 if (audio_size < 0) {
2450 /* if error, just output silence */
2451 is->audio_buf = NULL;
2452 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2454 if (is->show_mode != SHOW_MODE_VIDEO)
2455 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2456 is->audio_buf_size = audio_size;
2458 is->audio_buf_index = 0;
2460 len1 = is->audio_buf_size - is->audio_buf_index;
2463 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2464 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2466 memset(stream, 0, len1);
2467 if (!is->muted && is->audio_buf)
2468 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2472 is->audio_buf_index += len1;
2474 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2475 /* Let's assume the audio driver that is used by SDL has two periods. */
2476 if (!isnan(is->audio_clock)) {
2477 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);
2478 sync_clock_to_slave(&is->extclk, &is->audclk);
2482 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2484 SDL_AudioSpec wanted_spec, spec;
2486 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2487 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2488 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2490 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2492 wanted_nb_channels = atoi(env);
2493 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2495 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2496 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2497 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2499 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2500 wanted_spec.channels = wanted_nb_channels;
2501 wanted_spec.freq = wanted_sample_rate;
2502 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2503 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2506 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2507 next_sample_rate_idx--;
2508 wanted_spec.format = AUDIO_S16SYS;
2509 wanted_spec.silence = 0;
2510 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2511 wanted_spec.callback = sdl_audio_callback;
2512 wanted_spec.userdata = opaque;
2513 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2514 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2515 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2516 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2517 if (!wanted_spec.channels) {
2518 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2519 wanted_spec.channels = wanted_nb_channels;
2520 if (!wanted_spec.freq) {
2521 av_log(NULL, AV_LOG_ERROR,
2522 "No more combinations to try, audio open failed\n");
2526 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2528 if (spec.format != AUDIO_S16SYS) {
2529 av_log(NULL, AV_LOG_ERROR,
2530 "SDL advised audio format %d is not supported!\n", spec.format);
2533 if (spec.channels != wanted_spec.channels) {
2534 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2535 if (!wanted_channel_layout) {
2536 av_log(NULL, AV_LOG_ERROR,
2537 "SDL advised channel count %d is not supported!\n", spec.channels);
2542 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2543 audio_hw_params->freq = spec.freq;
2544 audio_hw_params->channel_layout = wanted_channel_layout;
2545 audio_hw_params->channels = spec.channels;
2546 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2547 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);
2548 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2549 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2555 /* open a given stream. Return 0 if OK */
2556 static int stream_component_open(VideoState *is, int stream_index)
2558 AVFormatContext *ic = is->ic;
2559 AVCodecContext *avctx;
2561 const char *forced_codec_name = NULL;
2562 AVDictionary *opts = NULL;
2563 AVDictionaryEntry *t = NULL;
2564 int sample_rate, nb_channels;
2565 int64_t channel_layout;
2567 int stream_lowres = lowres;
2569 if (stream_index < 0 || stream_index >= ic->nb_streams)
2572 avctx = avcodec_alloc_context3(NULL);
2574 return AVERROR(ENOMEM);
2576 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2579 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2581 codec = avcodec_find_decoder(avctx->codec_id);
2583 switch(avctx->codec_type){
2584 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2585 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2586 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2588 if (forced_codec_name)
2589 codec = avcodec_find_decoder_by_name(forced_codec_name);
2591 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2592 "No codec could be found with name '%s'\n", forced_codec_name);
2593 else av_log(NULL, AV_LOG_WARNING,
2594 "No codec could be found with id %d\n", avctx->codec_id);
2595 ret = AVERROR(EINVAL);
2599 avctx->codec_id = codec->id;
2600 if(stream_lowres > av_codec_get_max_lowres(codec)){
2601 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2602 av_codec_get_max_lowres(codec));
2603 stream_lowres = av_codec_get_max_lowres(codec);
2605 av_codec_set_lowres(avctx, stream_lowres);
2608 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2610 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2611 if (!av_dict_get(opts, "threads", NULL, 0))
2612 av_dict_set(&opts, "threads", "auto", 0);
2614 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2615 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2616 av_dict_set(&opts, "refcounted_frames", "1", 0);
2617 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2620 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2621 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2622 ret = AVERROR_OPTION_NOT_FOUND;
2627 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2628 switch (avctx->codec_type) {
2629 case AVMEDIA_TYPE_AUDIO:
2632 AVFilterContext *sink;
2634 is->audio_filter_src.freq = avctx->sample_rate;
2635 is->audio_filter_src.channels = avctx->channels;
2636 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2637 is->audio_filter_src.fmt = avctx->sample_fmt;
2638 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2640 sink = is->out_audio_filter;
2641 sample_rate = av_buffersink_get_sample_rate(sink);
2642 nb_channels = av_buffersink_get_channels(sink);
2643 channel_layout = av_buffersink_get_channel_layout(sink);
2646 sample_rate = avctx->sample_rate;
2647 nb_channels = avctx->channels;
2648 channel_layout = avctx->channel_layout;
2651 /* prepare audio output */
2652 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2654 is->audio_hw_buf_size = ret;
2655 is->audio_src = is->audio_tgt;
2656 is->audio_buf_size = 0;
2657 is->audio_buf_index = 0;
2659 /* init averaging filter */
2660 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2661 is->audio_diff_avg_count = 0;
2662 /* since we do not have a precise anough audio FIFO fullness,
2663 we correct audio sync only if larger than this threshold */
2664 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2666 is->audio_stream = stream_index;
2667 is->audio_st = ic->streams[stream_index];
2669 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2670 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2671 is->auddec.start_pts = is->audio_st->start_time;
2672 is->auddec.start_pts_tb = is->audio_st->time_base;
2674 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2678 case AVMEDIA_TYPE_VIDEO:
2679 is->video_stream = stream_index;
2680 is->video_st = ic->streams[stream_index];
2682 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2683 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2685 is->queue_attachments_req = 1;
2687 case AVMEDIA_TYPE_SUBTITLE:
2688 is->subtitle_stream = stream_index;
2689 is->subtitle_st = ic->streams[stream_index];
2691 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2692 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2701 avcodec_free_context(&avctx);
2703 av_dict_free(&opts);
2708 static int decode_interrupt_cb(void *ctx)
2710 VideoState *is = ctx;
2711 return is->abort_request;
2714 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2715 return stream_id < 0 ||
2716 queue->abort_request ||
2717 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2718 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2721 static int is_realtime(AVFormatContext *s)
2723 if( !strcmp(s->iformat->name, "rtp")
2724 || !strcmp(s->iformat->name, "rtsp")
2725 || !strcmp(s->iformat->name, "sdp")
2729 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2730 || !strncmp(s->filename, "udp:", 4)
2737 /* this thread gets the stream from the disk or the network */
2738 static int read_thread(void *arg)
2740 VideoState *is = arg;
2741 AVFormatContext *ic = NULL;
2743 int st_index[AVMEDIA_TYPE_NB];
2744 AVPacket pkt1, *pkt = &pkt1;
2745 int64_t stream_start_time;
2746 int pkt_in_play_range = 0;
2747 AVDictionaryEntry *t;
2748 SDL_mutex *wait_mutex = SDL_CreateMutex();
2749 int scan_all_pmts_set = 0;
2753 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2754 ret = AVERROR(ENOMEM);
2758 memset(st_index, -1, sizeof(st_index));
2759 is->last_video_stream = is->video_stream = -1;
2760 is->last_audio_stream = is->audio_stream = -1;
2761 is->last_subtitle_stream = is->subtitle_stream = -1;
2764 ic = avformat_alloc_context();
2766 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2767 ret = AVERROR(ENOMEM);
2770 ic->interrupt_callback.callback = decode_interrupt_cb;
2771 ic->interrupt_callback.opaque = is;
2772 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2773 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2774 scan_all_pmts_set = 1;
2776 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2778 print_error(is->filename, err);
2782 if (scan_all_pmts_set)
2783 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2785 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2786 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2787 ret = AVERROR_OPTION_NOT_FOUND;
2793 ic->flags |= AVFMT_FLAG_GENPTS;
2795 av_format_inject_global_side_data(ic);
2797 if (find_stream_info) {
2798 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2799 int orig_nb_streams = ic->nb_streams;
2801 err = avformat_find_stream_info(ic, opts);
2803 for (i = 0; i < orig_nb_streams; i++)
2804 av_dict_free(&opts[i]);
2808 av_log(NULL, AV_LOG_WARNING,
2809 "%s: could not find codec parameters\n", is->filename);
2816 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2818 if (seek_by_bytes < 0)
2819 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2821 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2823 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2824 window_title = av_asprintf("%s - %s", t->value, input_filename);
2826 /* if seeking requested, we execute it */
2827 if (start_time != AV_NOPTS_VALUE) {
2830 timestamp = start_time;
2831 /* add the stream start time */
2832 if (ic->start_time != AV_NOPTS_VALUE)
2833 timestamp += ic->start_time;
2834 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2836 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2837 is->filename, (double)timestamp / AV_TIME_BASE);
2841 is->realtime = is_realtime(ic);
2844 av_dump_format(ic, 0, is->filename, 0);
2846 for (i = 0; i < ic->nb_streams; i++) {
2847 AVStream *st = ic->streams[i];
2848 enum AVMediaType type = st->codecpar->codec_type;
2849 st->discard = AVDISCARD_ALL;
2850 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2851 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2854 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2855 if (wanted_stream_spec[i] && st_index[i] == -1) {
2856 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));
2857 st_index[i] = INT_MAX;
2862 st_index[AVMEDIA_TYPE_VIDEO] =
2863 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2864 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2866 st_index[AVMEDIA_TYPE_AUDIO] =
2867 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2868 st_index[AVMEDIA_TYPE_AUDIO],
2869 st_index[AVMEDIA_TYPE_VIDEO],
2871 if (!video_disable && !subtitle_disable)
2872 st_index[AVMEDIA_TYPE_SUBTITLE] =
2873 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2874 st_index[AVMEDIA_TYPE_SUBTITLE],
2875 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2876 st_index[AVMEDIA_TYPE_AUDIO] :
2877 st_index[AVMEDIA_TYPE_VIDEO]),
2880 is->show_mode = show_mode;
2881 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2882 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2883 AVCodecParameters *codecpar = st->codecpar;
2884 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2885 if (codecpar->width)
2886 set_default_window_size(codecpar->width, codecpar->height, sar);
2889 /* open the streams */
2890 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2891 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2895 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2896 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2898 if (is->show_mode == SHOW_MODE_NONE)
2899 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2901 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2902 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2905 if (is->video_stream < 0 && is->audio_stream < 0) {
2906 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2912 if (infinite_buffer < 0 && is->realtime)
2913 infinite_buffer = 1;
2916 if (is->abort_request)
2918 if (is->paused != is->last_paused) {
2919 is->last_paused = is->paused;
2921 is->read_pause_return = av_read_pause(ic);
2925 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2927 (!strcmp(ic->iformat->name, "rtsp") ||
2928 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2929 /* wait 10 ms to avoid trying to get another packet */
2936 int64_t seek_target = is->seek_pos;
2937 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2938 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2939 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2940 // of the seek_pos/seek_rel variables
2942 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2944 av_log(NULL, AV_LOG_ERROR,
2945 "%s: error while seeking\n", is->ic->filename);
2947 if (is->audio_stream >= 0) {
2948 packet_queue_flush(&is->audioq);
2949 packet_queue_put(&is->audioq, &flush_pkt);
2951 if (is->subtitle_stream >= 0) {
2952 packet_queue_flush(&is->subtitleq);
2953 packet_queue_put(&is->subtitleq, &flush_pkt);
2955 if (is->video_stream >= 0) {
2956 packet_queue_flush(&is->videoq);
2957 packet_queue_put(&is->videoq, &flush_pkt);
2959 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2960 set_clock(&is->extclk, NAN, 0);
2962 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2966 is->queue_attachments_req = 1;
2969 step_to_next_frame(is);
2971 if (is->queue_attachments_req) {
2972 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2973 AVPacket copy = { 0 };
2974 if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0)
2976 packet_queue_put(&is->videoq, ©);
2977 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2979 is->queue_attachments_req = 0;
2982 /* if the queue are full, no need to read more */
2983 if (infinite_buffer<1 &&
2984 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2985 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2986 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2987 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2989 SDL_LockMutex(wait_mutex);
2990 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2991 SDL_UnlockMutex(wait_mutex);
2995 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2996 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2997 if (loop != 1 && (!loop || --loop)) {
2998 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2999 } else if (autoexit) {
3004 ret = av_read_frame(ic, pkt);
3006 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3007 if (is->video_stream >= 0)
3008 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3009 if (is->audio_stream >= 0)
3010 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3011 if (is->subtitle_stream >= 0)
3012 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3015 if (ic->pb && ic->pb->error)
3017 SDL_LockMutex(wait_mutex);
3018 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3019 SDL_UnlockMutex(wait_mutex);
3024 /* check if packet is in play range specified by user, then queue, otherwise discard */
3025 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3026 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3027 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3028 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3029 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3030 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3031 <= ((double)duration / 1000000);
3032 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3033 packet_queue_put(&is->audioq, pkt);
3034 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3035 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3036 packet_queue_put(&is->videoq, pkt);
3037 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3038 packet_queue_put(&is->subtitleq, pkt);
3040 av_packet_unref(pkt);
3047 avformat_close_input(&ic);
3052 event.type = FF_QUIT_EVENT;
3053 event.user.data1 = is;
3054 SDL_PushEvent(&event);
3056 SDL_DestroyMutex(wait_mutex);
3060 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3064 is = av_mallocz(sizeof(VideoState));
3067 is->filename = av_strdup(filename);
3070 is->iformat = iformat;
3074 /* start video display */
3075 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3077 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3079 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3082 if (packet_queue_init(&is->videoq) < 0 ||
3083 packet_queue_init(&is->audioq) < 0 ||
3084 packet_queue_init(&is->subtitleq) < 0)
3087 if (!(is->continue_read_thread = SDL_CreateCond())) {
3088 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3092 init_clock(&is->vidclk, &is->videoq.serial);
3093 init_clock(&is->audclk, &is->audioq.serial);
3094 init_clock(&is->extclk, &is->extclk.serial);
3095 is->audio_clock_serial = -1;
3096 if (startup_volume < 0)
3097 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3098 if (startup_volume > 100)
3099 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3100 startup_volume = av_clip(startup_volume, 0, 100);
3101 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3102 is->audio_volume = startup_volume;
3104 is->av_sync_type = av_sync_type;
3105 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3106 if (!is->read_tid) {
3107 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3115 static void stream_cycle_channel(VideoState *is, int codec_type)
3117 AVFormatContext *ic = is->ic;
3118 int start_index, stream_index;
3121 AVProgram *p = NULL;
3122 int nb_streams = is->ic->nb_streams;
3124 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3125 start_index = is->last_video_stream;
3126 old_index = is->video_stream;
3127 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3128 start_index = is->last_audio_stream;
3129 old_index = is->audio_stream;
3131 start_index = is->last_subtitle_stream;
3132 old_index = is->subtitle_stream;
3134 stream_index = start_index;
3136 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3137 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3139 nb_streams = p->nb_stream_indexes;
3140 for (start_index = 0; start_index < nb_streams; start_index++)
3141 if (p->stream_index[start_index] == stream_index)
3143 if (start_index == nb_streams)
3145 stream_index = start_index;
3150 if (++stream_index >= nb_streams)
3152 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3155 is->last_subtitle_stream = -1;
3158 if (start_index == -1)
3162 if (stream_index == start_index)
3164 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3165 if (st->codecpar->codec_type == codec_type) {
3166 /* check that parameters are OK */
3167 switch (codec_type) {
3168 case AVMEDIA_TYPE_AUDIO:
3169 if (st->codecpar->sample_rate != 0 &&
3170 st->codecpar->channels != 0)
3173 case AVMEDIA_TYPE_VIDEO:
3174 case AVMEDIA_TYPE_SUBTITLE:
3182 if (p && stream_index != -1)
3183 stream_index = p->stream_index[stream_index];
3184 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3185 av_get_media_type_string(codec_type),
3189 stream_component_close(is, old_index);
3190 stream_component_open(is, stream_index);
3194 static void toggle_full_screen(VideoState *is)
3196 is_full_screen = !is_full_screen;
3197 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3200 static void toggle_audio_display(VideoState *is)
3202 int next = is->show_mode;
3204 next = (next + 1) % SHOW_MODE_NB;
3205 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3206 if (is->show_mode != next) {
3207 is->force_refresh = 1;
3208 is->show_mode = next;
3212 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3213 double remaining_time = 0.0;
3215 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3216 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3220 if (remaining_time > 0.0)
3221 av_usleep((int64_t)(remaining_time * 1000000.0));
3222 remaining_time = REFRESH_RATE;
3223 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3224 video_refresh(is, &remaining_time);
3229 static void seek_chapter(VideoState *is, int incr)
3231 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3234 if (!is->ic->nb_chapters)
3237 /* find the current chapter */
3238 for (i = 0; i < is->ic->nb_chapters; i++) {
3239 AVChapter *ch = is->ic->chapters[i];
3240 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3248 if (i >= is->ic->nb_chapters)
3251 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3252 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3253 AV_TIME_BASE_Q), 0, 0);
3256 /* handle an event sent by the GUI */
3257 static void event_loop(VideoState *cur_stream)
3260 double incr, pos, frac;
3264 refresh_loop_wait_event(cur_stream, &event);
3265 switch (event.type) {
3267 if (exit_on_keydown) {
3268 do_exit(cur_stream);
3271 switch (event.key.keysym.sym) {
3274 do_exit(cur_stream);
3277 toggle_full_screen(cur_stream);
3278 cur_stream->force_refresh = 1;
3282 toggle_pause(cur_stream);
3285 toggle_mute(cur_stream);
3287 case SDLK_KP_MULTIPLY:
3289 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3291 case SDLK_KP_DIVIDE:
3293 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3295 case SDLK_s: // S: Step to next frame
3296 step_to_next_frame(cur_stream);
3299 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3302 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3305 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3306 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3307 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3310 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3314 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3315 if (++cur_stream->vfilter_idx >= nb_vfilters)
3316 cur_stream->vfilter_idx = 0;
3318 cur_stream->vfilter_idx = 0;
3319 toggle_audio_display(cur_stream);
3322 toggle_audio_display(cur_stream);
3326 if (cur_stream->ic->nb_chapters <= 1) {
3330 seek_chapter(cur_stream, 1);
3333 if (cur_stream->ic->nb_chapters <= 1) {
3337 seek_chapter(cur_stream, -1);
3351 if (seek_by_bytes) {
3353 if (pos < 0 && cur_stream->video_stream >= 0)
3354 pos = frame_queue_last_pos(&cur_stream->pictq);
3355 if (pos < 0 && cur_stream->audio_stream >= 0)
3356 pos = frame_queue_last_pos(&cur_stream->sampq);
3358 pos = avio_tell(cur_stream->ic->pb);
3359 if (cur_stream->ic->bit_rate)
3360 incr *= cur_stream->ic->bit_rate / 8.0;
3364 stream_seek(cur_stream, pos, incr, 1);
3366 pos = get_master_clock(cur_stream);
3368 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3370 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3371 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3372 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3379 case SDL_MOUSEBUTTONDOWN:
3380 if (exit_on_mousedown) {
3381 do_exit(cur_stream);
3384 if (event.button.button == SDL_BUTTON_LEFT) {
3385 static int64_t last_mouse_left_click = 0;
3386 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3387 toggle_full_screen(cur_stream);
3388 cur_stream->force_refresh = 1;
3389 last_mouse_left_click = 0;
3391 last_mouse_left_click = av_gettime_relative();
3394 case SDL_MOUSEMOTION:
3395 if (cursor_hidden) {
3399 cursor_last_shown = av_gettime_relative();
3400 if (event.type == SDL_MOUSEBUTTONDOWN) {
3401 if (event.button.button != SDL_BUTTON_RIGHT)
3405 if (!(event.motion.state & SDL_BUTTON_RMASK))
3409 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3410 uint64_t size = avio_size(cur_stream->ic->pb);
3411 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3415 int tns, thh, tmm, tss;
3416 tns = cur_stream->ic->duration / 1000000LL;
3418 tmm = (tns % 3600) / 60;
3420 frac = x / cur_stream->width;
3423 mm = (ns % 3600) / 60;
3425 av_log(NULL, AV_LOG_INFO,
3426 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3427 hh, mm, ss, thh, tmm, tss);
3428 ts = frac * cur_stream->ic->duration;
3429 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3430 ts += cur_stream->ic->start_time;
3431 stream_seek(cur_stream, ts, 0, 0);
3434 case SDL_WINDOWEVENT:
3435 switch (event.window.event) {
3436 case SDL_WINDOWEVENT_RESIZED:
3437 screen_width = cur_stream->width = event.window.data1;
3438 screen_height = cur_stream->height = event.window.data2;
3439 if (cur_stream->vis_texture) {
3440 SDL_DestroyTexture(cur_stream->vis_texture);
3441 cur_stream->vis_texture = NULL;
3443 case SDL_WINDOWEVENT_EXPOSED:
3444 cur_stream->force_refresh = 1;
3449 do_exit(cur_stream);
3457 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3459 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3460 return opt_default(NULL, "video_size", arg);
3463 static int opt_width(void *optctx, const char *opt, const char *arg)
3465 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3469 static int opt_height(void *optctx, const char *opt, const char *arg)
3471 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3475 static int opt_format(void *optctx, const char *opt, const char *arg)
3477 file_iformat = av_find_input_format(arg);
3478 if (!file_iformat) {
3479 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3480 return AVERROR(EINVAL);
3485 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3487 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3488 return opt_default(NULL, "pixel_format", arg);
3491 static int opt_sync(void *optctx, const char *opt, const char *arg)
3493 if (!strcmp(arg, "audio"))
3494 av_sync_type = AV_SYNC_AUDIO_MASTER;
3495 else if (!strcmp(arg, "video"))
3496 av_sync_type = AV_SYNC_VIDEO_MASTER;
3497 else if (!strcmp(arg, "ext"))
3498 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3500 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3506 static int opt_seek(void *optctx, const char *opt, const char *arg)
3508 start_time = parse_time_or_die(opt, arg, 1);
3512 static int opt_duration(void *optctx, const char *opt, const char *arg)
3514 duration = parse_time_or_die(opt, arg, 1);
3518 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3520 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3521 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3522 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3523 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3527 static void opt_input_file(void *optctx, const char *filename)
3529 if (input_filename) {
3530 av_log(NULL, AV_LOG_FATAL,
3531 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3532 filename, input_filename);
3535 if (!strcmp(filename, "-"))
3537 input_filename = filename;
3540 static int opt_codec(void *optctx, const char *opt, const char *arg)
3542 const char *spec = strchr(opt, ':');
3544 av_log(NULL, AV_LOG_ERROR,
3545 "No media specifier was specified in '%s' in option '%s'\n",
3547 return AVERROR(EINVAL);
3551 case 'a' : audio_codec_name = arg; break;
3552 case 's' : subtitle_codec_name = arg; break;
3553 case 'v' : video_codec_name = arg; break;
3555 av_log(NULL, AV_LOG_ERROR,
3556 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3557 return AVERROR(EINVAL);
3564 static const OptionDef options[] = {
3565 CMDUTILS_COMMON_OPTIONS
3566 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3567 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3568 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3569 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3570 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3571 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3572 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3573 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3574 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3575 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3576 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3577 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3578 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3579 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3580 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3581 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3582 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3583 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3584 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3585 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3586 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3587 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3588 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3589 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3590 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3591 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3592 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3593 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3594 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3595 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3596 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3598 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3599 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3601 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3602 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3603 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3604 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3605 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3606 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3607 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3608 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3609 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3610 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3611 "read and decode the streams to fill missing information with heuristics" },
3615 static void show_usage(void)
3617 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3618 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3619 av_log(NULL, AV_LOG_INFO, "\n");
3622 void show_help_default(const char *opt, const char *arg)
3624 av_log_set_callback(log_callback_help);
3626 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3627 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3629 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3630 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3631 #if !CONFIG_AVFILTER
3632 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3634 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3636 printf("\nWhile playing:\n"
3638 "f toggle full screen\n"
3641 "9, 0 decrease and increase volume respectively\n"
3642 "/, * decrease and increase volume respectively\n"
3643 "a cycle audio channel in the current program\n"
3644 "v cycle video channel\n"
3645 "t cycle subtitle channel in the current program\n"
3647 "w cycle video filters or show modes\n"
3648 "s activate frame-step mode\n"
3649 "left/right seek backward/forward 10 seconds\n"
3650 "down/up seek backward/forward 1 minute\n"
3651 "page down/page up seek backward/forward 10 minutes\n"
3652 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3653 "left double-click toggle full screen\n"
3657 static int lockmgr(void **mtx, enum AVLockOp op)
3660 case AV_LOCK_CREATE:
3661 *mtx = SDL_CreateMutex();
3663 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3667 case AV_LOCK_OBTAIN:
3668 return !!SDL_LockMutex(*mtx);
3669 case AV_LOCK_RELEASE:
3670 return !!SDL_UnlockMutex(*mtx);
3671 case AV_LOCK_DESTROY:
3672 SDL_DestroyMutex(*mtx);
3678 /* Called from the main */
3679 int main(int argc, char **argv)
3686 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3687 parse_loglevel(argc, argv, options);
3689 /* register all codecs, demux and protocols */
3691 avdevice_register_all();
3694 avfilter_register_all();
3697 avformat_network_init();
3701 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3702 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3704 show_banner(argc, argv, options);
3706 parse_options(NULL, argc, argv, options, opt_input_file);
3708 if (!input_filename) {
3710 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3711 av_log(NULL, AV_LOG_FATAL,
3712 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3716 if (display_disable) {
3719 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3721 flags &= ~SDL_INIT_AUDIO;
3723 /* Try to work around an occasional ALSA buffer underflow issue when the
3724 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3725 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3726 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3728 if (display_disable)
3729 flags &= ~SDL_INIT_VIDEO;
3730 if (SDL_Init (flags)) {
3731 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3732 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3736 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3737 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3739 if (av_lockmgr_register(lockmgr)) {
3740 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3744 av_init_packet(&flush_pkt);
3745 flush_pkt.data = (uint8_t *)&flush_pkt;
3747 is = stream_open(input_filename, file_iformat);
3749 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");