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;
366 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
368 GROW_ARRAY(vfilters_list, nb_vfilters);
369 vfilters_list[nb_vfilters - 1] = arg;
375 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
376 enum AVSampleFormat fmt2, int64_t channel_count2)
378 /* If channel count == 1, planar and non-planar formats are the same */
379 if (channel_count1 == 1 && channel_count2 == 1)
380 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
382 return channel_count1 != channel_count2 || fmt1 != fmt2;
386 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
388 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
389 return channel_layout;
394 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
396 MyAVPacketList *pkt1;
398 if (q->abort_request)
401 pkt1 = av_malloc(sizeof(MyAVPacketList));
406 if (pkt == &flush_pkt)
408 pkt1->serial = q->serial;
413 q->last_pkt->next = pkt1;
416 q->size += pkt1->pkt.size + sizeof(*pkt1);
417 q->duration += pkt1->pkt.duration;
418 /* XXX: should duplicate packet data in DV case */
419 SDL_CondSignal(q->cond);
423 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
427 SDL_LockMutex(q->mutex);
428 ret = packet_queue_put_private(q, pkt);
429 SDL_UnlockMutex(q->mutex);
431 if (pkt != &flush_pkt && ret < 0)
432 av_packet_unref(pkt);
437 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
439 AVPacket pkt1, *pkt = &pkt1;
443 pkt->stream_index = stream_index;
444 return packet_queue_put(q, pkt);
447 /* packet queue handling */
448 static int packet_queue_init(PacketQueue *q)
450 memset(q, 0, sizeof(PacketQueue));
451 q->mutex = SDL_CreateMutex();
453 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
454 return AVERROR(ENOMEM);
456 q->cond = SDL_CreateCond();
458 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
459 return AVERROR(ENOMEM);
461 q->abort_request = 1;
465 static void packet_queue_flush(PacketQueue *q)
467 MyAVPacketList *pkt, *pkt1;
469 SDL_LockMutex(q->mutex);
470 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
472 av_packet_unref(&pkt->pkt);
480 SDL_UnlockMutex(q->mutex);
483 static void packet_queue_destroy(PacketQueue *q)
485 packet_queue_flush(q);
486 SDL_DestroyMutex(q->mutex);
487 SDL_DestroyCond(q->cond);
490 static void packet_queue_abort(PacketQueue *q)
492 SDL_LockMutex(q->mutex);
494 q->abort_request = 1;
496 SDL_CondSignal(q->cond);
498 SDL_UnlockMutex(q->mutex);
501 static void packet_queue_start(PacketQueue *q)
503 SDL_LockMutex(q->mutex);
504 q->abort_request = 0;
505 packet_queue_put_private(q, &flush_pkt);
506 SDL_UnlockMutex(q->mutex);
509 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
510 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
512 MyAVPacketList *pkt1;
515 SDL_LockMutex(q->mutex);
518 if (q->abort_request) {
525 q->first_pkt = pkt1->next;
529 q->size -= pkt1->pkt.size + sizeof(*pkt1);
530 q->duration -= pkt1->pkt.duration;
533 *serial = pkt1->serial;
541 SDL_CondWait(q->cond, q->mutex);
544 SDL_UnlockMutex(q->mutex);
548 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
549 memset(d, 0, sizeof(Decoder));
552 d->empty_queue_cond = empty_queue_cond;
553 d->start_pts = AV_NOPTS_VALUE;
557 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
558 int ret = AVERROR(EAGAIN);
563 if (d->queue->serial == d->pkt_serial) {
565 if (d->queue->abort_request)
568 switch (d->avctx->codec_type) {
569 case AVMEDIA_TYPE_VIDEO:
570 ret = avcodec_receive_frame(d->avctx, frame);
572 if (decoder_reorder_pts == -1) {
573 frame->pts = frame->best_effort_timestamp;
574 } else if (!decoder_reorder_pts) {
575 frame->pts = frame->pkt_dts;
579 case AVMEDIA_TYPE_AUDIO:
580 ret = avcodec_receive_frame(d->avctx, frame);
582 AVRational tb = (AVRational){1, frame->sample_rate};
583 if (frame->pts != AV_NOPTS_VALUE)
584 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
585 else if (d->next_pts != AV_NOPTS_VALUE)
586 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
587 if (frame->pts != AV_NOPTS_VALUE) {
588 d->next_pts = frame->pts + frame->nb_samples;
594 if (ret == AVERROR_EOF) {
595 d->finished = d->pkt_serial;
596 avcodec_flush_buffers(d->avctx);
601 } while (ret != AVERROR(EAGAIN));
605 if (d->queue->nb_packets == 0)
606 SDL_CondSignal(d->empty_queue_cond);
607 if (d->packet_pending) {
608 av_packet_move_ref(&pkt, &d->pkt);
609 d->packet_pending = 0;
611 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
614 } while (d->queue->serial != d->pkt_serial);
616 if (pkt.data == flush_pkt.data) {
617 avcodec_flush_buffers(d->avctx);
619 d->next_pts = d->start_pts;
620 d->next_pts_tb = d->start_pts_tb;
622 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
624 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
626 ret = AVERROR(EAGAIN);
628 if (got_frame && !pkt.data) {
629 d->packet_pending = 1;
630 av_packet_move_ref(&d->pkt, &pkt);
632 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
635 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
636 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
637 d->packet_pending = 1;
638 av_packet_move_ref(&d->pkt, &pkt);
641 av_packet_unref(&pkt);
646 static void decoder_destroy(Decoder *d) {
647 av_packet_unref(&d->pkt);
648 avcodec_free_context(&d->avctx);
651 static void frame_queue_unref_item(Frame *vp)
653 av_frame_unref(vp->frame);
654 avsubtitle_free(&vp->sub);
657 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
660 memset(f, 0, sizeof(FrameQueue));
661 if (!(f->mutex = SDL_CreateMutex())) {
662 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
663 return AVERROR(ENOMEM);
665 if (!(f->cond = SDL_CreateCond())) {
666 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
667 return AVERROR(ENOMEM);
670 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
671 f->keep_last = !!keep_last;
672 for (i = 0; i < f->max_size; i++)
673 if (!(f->queue[i].frame = av_frame_alloc()))
674 return AVERROR(ENOMEM);
678 static void frame_queue_destory(FrameQueue *f)
681 for (i = 0; i < f->max_size; i++) {
682 Frame *vp = &f->queue[i];
683 frame_queue_unref_item(vp);
684 av_frame_free(&vp->frame);
686 SDL_DestroyMutex(f->mutex);
687 SDL_DestroyCond(f->cond);
690 static void frame_queue_signal(FrameQueue *f)
692 SDL_LockMutex(f->mutex);
693 SDL_CondSignal(f->cond);
694 SDL_UnlockMutex(f->mutex);
697 static Frame *frame_queue_peek(FrameQueue *f)
699 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
702 static Frame *frame_queue_peek_next(FrameQueue *f)
704 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
707 static Frame *frame_queue_peek_last(FrameQueue *f)
709 return &f->queue[f->rindex];
712 static Frame *frame_queue_peek_writable(FrameQueue *f)
714 /* wait until we have space to put a new frame */
715 SDL_LockMutex(f->mutex);
716 while (f->size >= f->max_size &&
717 !f->pktq->abort_request) {
718 SDL_CondWait(f->cond, f->mutex);
720 SDL_UnlockMutex(f->mutex);
722 if (f->pktq->abort_request)
725 return &f->queue[f->windex];
728 static Frame *frame_queue_peek_readable(FrameQueue *f)
730 /* wait until we have a readable a new frame */
731 SDL_LockMutex(f->mutex);
732 while (f->size - f->rindex_shown <= 0 &&
733 !f->pktq->abort_request) {
734 SDL_CondWait(f->cond, f->mutex);
736 SDL_UnlockMutex(f->mutex);
738 if (f->pktq->abort_request)
741 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
744 static void frame_queue_push(FrameQueue *f)
746 if (++f->windex == f->max_size)
748 SDL_LockMutex(f->mutex);
750 SDL_CondSignal(f->cond);
751 SDL_UnlockMutex(f->mutex);
754 static void frame_queue_next(FrameQueue *f)
756 if (f->keep_last && !f->rindex_shown) {
760 frame_queue_unref_item(&f->queue[f->rindex]);
761 if (++f->rindex == f->max_size)
763 SDL_LockMutex(f->mutex);
765 SDL_CondSignal(f->cond);
766 SDL_UnlockMutex(f->mutex);
769 /* return the number of undisplayed frames in the queue */
770 static int frame_queue_nb_remaining(FrameQueue *f)
772 return f->size - f->rindex_shown;
775 /* return last shown position */
776 static int64_t frame_queue_last_pos(FrameQueue *f)
778 Frame *fp = &f->queue[f->rindex];
779 if (f->rindex_shown && fp->serial == f->pktq->serial)
785 static void decoder_abort(Decoder *d, FrameQueue *fq)
787 packet_queue_abort(d->queue);
788 frame_queue_signal(fq);
789 SDL_WaitThread(d->decoder_tid, NULL);
790 d->decoder_tid = NULL;
791 packet_queue_flush(d->queue);
794 static inline void fill_rectangle(int x, int y, int w, int h)
802 SDL_RenderFillRect(renderer, &rect);
805 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
809 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
812 SDL_DestroyTexture(*texture);
813 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
815 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
818 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
820 memset(pixels, 0, pitch * new_height);
821 SDL_UnlockTexture(*texture);
827 static void calculate_display_rect(SDL_Rect *rect,
828 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
829 int pic_width, int pic_height, AVRational pic_sar)
832 int width, height, x, y;
834 if (pic_sar.num == 0)
837 aspect_ratio = av_q2d(pic_sar);
839 if (aspect_ratio <= 0.0)
841 aspect_ratio *= (float)pic_width / (float)pic_height;
843 /* XXX: we suppose the screen has a 1.0 pixel ratio */
845 width = lrint(height * aspect_ratio) & ~1;
846 if (width > scr_width) {
848 height = lrint(width / aspect_ratio) & ~1;
850 x = (scr_width - width) / 2;
851 y = (scr_height - height) / 2;
852 rect->x = scr_xleft + x;
853 rect->y = scr_ytop + y;
854 rect->w = FFMAX(width, 1);
855 rect->h = FFMAX(height, 1);
858 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
860 switch (frame->format) {
861 case AV_PIX_FMT_YUV420P:
862 if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
863 av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
866 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
867 frame->data[1], frame->linesize[1],
868 frame->data[2], frame->linesize[2]);
870 case AV_PIX_FMT_BGRA:
871 if (frame->linesize[0] < 0) {
872 ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
874 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
878 /* This should only happen if we are not using avfilter... */
879 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
880 frame->width, frame->height, frame->format, frame->width, frame->height,
881 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
882 if (*img_convert_ctx != NULL) {
885 if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) {
886 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
887 0, frame->height, pixels, pitch);
888 SDL_UnlockTexture(tex);
891 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
899 static void video_image_display(VideoState *is)
905 vp = frame_queue_peek_last(&is->pictq);
906 if (is->subtitle_st) {
907 if (frame_queue_nb_remaining(&is->subpq) > 0) {
908 sp = frame_queue_peek(&is->subpq);
910 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
915 if (!sp->width || !sp->height) {
916 sp->width = vp->width;
917 sp->height = vp->height;
919 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
922 for (i = 0; i < sp->sub.num_rects; i++) {
923 AVSubtitleRect *sub_rect = sp->sub.rects[i];
925 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
926 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
927 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
928 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
930 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
931 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
932 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
933 0, NULL, NULL, NULL);
934 if (!is->sub_convert_ctx) {
935 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
938 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
939 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
940 0, sub_rect->h, pixels, pitch);
941 SDL_UnlockTexture(is->sub_texture);
951 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
954 int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888;
955 if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0)
957 if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
960 vp->flip_v = vp->frame->linesize[0] < 0;
963 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
965 #if USE_ONEPASS_SUBTITLE_RENDER
966 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
969 double xratio = (double)rect.w / (double)sp->width;
970 double yratio = (double)rect.h / (double)sp->height;
971 for (i = 0; i < sp->sub.num_rects; i++) {
972 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
973 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
974 .y = rect.y + sub_rect->y * yratio,
975 .w = sub_rect->w * xratio,
976 .h = sub_rect->h * yratio};
977 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
983 static inline int compute_mod(int a, int b)
985 return a < 0 ? a%b + b : a%b;
988 static void video_audio_display(VideoState *s)
990 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
991 int ch, channels, h, h2;
993 int rdft_bits, nb_freq;
995 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
997 nb_freq = 1 << (rdft_bits - 1);
999 /* compute display index : center on currently output samples */
1000 channels = s->audio_tgt.channels;
1001 nb_display_channels = channels;
1003 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1005 delay = s->audio_write_buf_size;
1008 /* to be more precise, we take into account the time spent since
1009 the last buffer computation */
1010 if (audio_callback_time) {
1011 time_diff = av_gettime_relative() - audio_callback_time;
1012 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1015 delay += 2 * data_used;
1016 if (delay < data_used)
1019 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1020 if (s->show_mode == SHOW_MODE_WAVES) {
1022 for (i = 0; i < 1000; i += channels) {
1023 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1024 int a = s->sample_array[idx];
1025 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1026 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1027 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1029 if (h < score && (b ^ c) < 0) {
1036 s->last_i_start = i_start;
1038 i_start = s->last_i_start;
1041 if (s->show_mode == SHOW_MODE_WAVES) {
1042 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1044 /* total height for one channel */
1045 h = s->height / nb_display_channels;
1046 /* graph height / 2 */
1048 for (ch = 0; ch < nb_display_channels; ch++) {
1050 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1051 for (x = 0; x < s->width; x++) {
1052 y = (s->sample_array[i] * h2) >> 15;
1059 fill_rectangle(s->xleft + x, ys, 1, y);
1061 if (i >= SAMPLE_ARRAY_SIZE)
1062 i -= SAMPLE_ARRAY_SIZE;
1066 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1068 for (ch = 1; ch < nb_display_channels; ch++) {
1069 y = s->ytop + ch * h;
1070 fill_rectangle(s->xleft, y, s->width, 1);
1073 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1076 nb_display_channels= FFMIN(nb_display_channels, 2);
1077 if (rdft_bits != s->rdft_bits) {
1078 av_rdft_end(s->rdft);
1079 av_free(s->rdft_data);
1080 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1081 s->rdft_bits = rdft_bits;
1082 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1084 if (!s->rdft || !s->rdft_data){
1085 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1086 s->show_mode = SHOW_MODE_WAVES;
1089 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1092 for (ch = 0; ch < nb_display_channels; ch++) {
1093 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1095 for (x = 0; x < 2 * nb_freq; x++) {
1096 double w = (x-nb_freq) * (1.0 / nb_freq);
1097 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1099 if (i >= SAMPLE_ARRAY_SIZE)
1100 i -= SAMPLE_ARRAY_SIZE;
1102 av_rdft_calc(s->rdft, data[ch]);
1104 /* Least efficient way to do this, we should of course
1105 * directly access it but it is more than fast enough. */
1106 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1108 pixels += pitch * s->height;
1109 for (y = 0; y < s->height; y++) {
1110 double w = 1 / sqrt(nb_freq);
1111 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]));
1112 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1117 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1119 SDL_UnlockTexture(s->vis_texture);
1121 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1125 if (s->xpos >= s->width)
1130 static void stream_component_close(VideoState *is, int stream_index)
1132 AVFormatContext *ic = is->ic;
1133 AVCodecParameters *codecpar;
1135 if (stream_index < 0 || stream_index >= ic->nb_streams)
1137 codecpar = ic->streams[stream_index]->codecpar;
1139 switch (codecpar->codec_type) {
1140 case AVMEDIA_TYPE_AUDIO:
1141 decoder_abort(&is->auddec, &is->sampq);
1143 decoder_destroy(&is->auddec);
1144 swr_free(&is->swr_ctx);
1145 av_freep(&is->audio_buf1);
1146 is->audio_buf1_size = 0;
1147 is->audio_buf = NULL;
1150 av_rdft_end(is->rdft);
1151 av_freep(&is->rdft_data);
1156 case AVMEDIA_TYPE_VIDEO:
1157 decoder_abort(&is->viddec, &is->pictq);
1158 decoder_destroy(&is->viddec);
1160 case AVMEDIA_TYPE_SUBTITLE:
1161 decoder_abort(&is->subdec, &is->subpq);
1162 decoder_destroy(&is->subdec);
1168 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1169 switch (codecpar->codec_type) {
1170 case AVMEDIA_TYPE_AUDIO:
1171 is->audio_st = NULL;
1172 is->audio_stream = -1;
1174 case AVMEDIA_TYPE_VIDEO:
1175 is->video_st = NULL;
1176 is->video_stream = -1;
1178 case AVMEDIA_TYPE_SUBTITLE:
1179 is->subtitle_st = NULL;
1180 is->subtitle_stream = -1;
1187 static void stream_close(VideoState *is)
1189 /* XXX: use a special url_shutdown call to abort parse cleanly */
1190 is->abort_request = 1;
1191 SDL_WaitThread(is->read_tid, NULL);
1193 /* close each stream */
1194 if (is->audio_stream >= 0)
1195 stream_component_close(is, is->audio_stream);
1196 if (is->video_stream >= 0)
1197 stream_component_close(is, is->video_stream);
1198 if (is->subtitle_stream >= 0)
1199 stream_component_close(is, is->subtitle_stream);
1201 avformat_close_input(&is->ic);
1203 packet_queue_destroy(&is->videoq);
1204 packet_queue_destroy(&is->audioq);
1205 packet_queue_destroy(&is->subtitleq);
1207 /* free all pictures */
1208 frame_queue_destory(&is->pictq);
1209 frame_queue_destory(&is->sampq);
1210 frame_queue_destory(&is->subpq);
1211 SDL_DestroyCond(is->continue_read_thread);
1212 sws_freeContext(is->img_convert_ctx);
1213 sws_freeContext(is->sub_convert_ctx);
1214 av_free(is->filename);
1215 if (is->vis_texture)
1216 SDL_DestroyTexture(is->vis_texture);
1217 if (is->vid_texture)
1218 SDL_DestroyTexture(is->vid_texture);
1219 if (is->sub_texture)
1220 SDL_DestroyTexture(is->sub_texture);
1224 static void do_exit(VideoState *is)
1230 SDL_DestroyRenderer(renderer);
1232 SDL_DestroyWindow(window);
1233 av_lockmgr_register(NULL);
1236 av_freep(&vfilters_list);
1238 avformat_network_deinit();
1242 av_log(NULL, AV_LOG_QUIET, "%s", "");
1246 static void sigterm_handler(int sig)
1251 static void set_default_window_size(int width, int height, AVRational sar)
1254 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1255 default_width = rect.w;
1256 default_height = rect.h;
1259 static int video_open(VideoState *is)
1272 int flags = SDL_WINDOW_SHOWN;
1274 window_title = input_filename;
1276 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1278 flags |= SDL_WINDOW_BORDERLESS;
1280 flags |= SDL_WINDOW_RESIZABLE;
1281 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1282 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1284 SDL_RendererInfo info;
1285 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1287 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1288 renderer = SDL_CreateRenderer(window, -1, 0);
1291 if (!SDL_GetRendererInfo(renderer, &info))
1292 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1296 SDL_SetWindowSize(window, w, h);
1299 if (!window || !renderer) {
1300 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1310 /* display the current picture, if any */
1311 static void video_display(VideoState *is)
1316 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1317 SDL_RenderClear(renderer);
1318 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1319 video_audio_display(is);
1320 else if (is->video_st)
1321 video_image_display(is);
1322 SDL_RenderPresent(renderer);
1325 static double get_clock(Clock *c)
1327 if (*c->queue_serial != c->serial)
1332 double time = av_gettime_relative() / 1000000.0;
1333 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1337 static void set_clock_at(Clock *c, double pts, int serial, double time)
1340 c->last_updated = time;
1341 c->pts_drift = c->pts - time;
1345 static void set_clock(Clock *c, double pts, int serial)
1347 double time = av_gettime_relative() / 1000000.0;
1348 set_clock_at(c, pts, serial, time);
1351 static void set_clock_speed(Clock *c, double speed)
1353 set_clock(c, get_clock(c), c->serial);
1357 static void init_clock(Clock *c, int *queue_serial)
1361 c->queue_serial = queue_serial;
1362 set_clock(c, NAN, -1);
1365 static void sync_clock_to_slave(Clock *c, Clock *slave)
1367 double clock = get_clock(c);
1368 double slave_clock = get_clock(slave);
1369 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1370 set_clock(c, slave_clock, slave->serial);
1373 static int get_master_sync_type(VideoState *is) {
1374 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1376 return AV_SYNC_VIDEO_MASTER;
1378 return AV_SYNC_AUDIO_MASTER;
1379 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1381 return AV_SYNC_AUDIO_MASTER;
1383 return AV_SYNC_EXTERNAL_CLOCK;
1385 return AV_SYNC_EXTERNAL_CLOCK;
1389 /* get the current master clock value */
1390 static double get_master_clock(VideoState *is)
1394 switch (get_master_sync_type(is)) {
1395 case AV_SYNC_VIDEO_MASTER:
1396 val = get_clock(&is->vidclk);
1398 case AV_SYNC_AUDIO_MASTER:
1399 val = get_clock(&is->audclk);
1402 val = get_clock(&is->extclk);
1408 static void check_external_clock_speed(VideoState *is) {
1409 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1410 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1411 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1412 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1413 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1414 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1416 double speed = is->extclk.speed;
1418 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1422 /* seek in the stream */
1423 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1425 if (!is->seek_req) {
1428 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1430 is->seek_flags |= AVSEEK_FLAG_BYTE;
1432 SDL_CondSignal(is->continue_read_thread);
1436 /* pause or resume the video */
1437 static void stream_toggle_pause(VideoState *is)
1440 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1441 if (is->read_pause_return != AVERROR(ENOSYS)) {
1442 is->vidclk.paused = 0;
1444 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1446 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1447 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1450 static void toggle_pause(VideoState *is)
1452 stream_toggle_pause(is);
1456 static void toggle_mute(VideoState *is)
1458 is->muted = !is->muted;
1461 static void update_volume(VideoState *is, int sign, double step)
1463 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1464 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1465 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1468 static void step_to_next_frame(VideoState *is)
1470 /* if the stream is paused unpause it, then step */
1472 stream_toggle_pause(is);
1476 static double compute_target_delay(double delay, VideoState *is)
1478 double sync_threshold, diff = 0;
1480 /* update delay to follow master synchronisation source */
1481 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1482 /* if video is slave, we try to correct big delays by
1483 duplicating or deleting a frame */
1484 diff = get_clock(&is->vidclk) - get_master_clock(is);
1486 /* skip or repeat frame. We take into account the
1487 delay to compute the threshold. I still don't know
1488 if it is the best guess */
1489 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1490 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1491 if (diff <= -sync_threshold)
1492 delay = FFMAX(0, delay + diff);
1493 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1494 delay = delay + diff;
1495 else if (diff >= sync_threshold)
1500 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1506 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1507 if (vp->serial == nextvp->serial) {
1508 double duration = nextvp->pts - vp->pts;
1509 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1510 return vp->duration;
1518 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1519 /* update current video pts */
1520 set_clock(&is->vidclk, pts, serial);
1521 sync_clock_to_slave(&is->extclk, &is->vidclk);
1524 /* called to display each frame */
1525 static void video_refresh(void *opaque, double *remaining_time)
1527 VideoState *is = opaque;
1532 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1533 check_external_clock_speed(is);
1535 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1536 time = av_gettime_relative() / 1000000.0;
1537 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1539 is->last_vis_time = time;
1541 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1546 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1547 // nothing to do, no picture to display in the queue
1549 double last_duration, duration, delay;
1552 /* dequeue the picture */
1553 lastvp = frame_queue_peek_last(&is->pictq);
1554 vp = frame_queue_peek(&is->pictq);
1556 if (vp->serial != is->videoq.serial) {
1557 frame_queue_next(&is->pictq);
1561 if (lastvp->serial != vp->serial)
1562 is->frame_timer = av_gettime_relative() / 1000000.0;
1567 /* compute nominal last_duration */
1568 last_duration = vp_duration(is, lastvp, vp);
1569 delay = compute_target_delay(last_duration, is);
1571 time= av_gettime_relative()/1000000.0;
1572 if (time < is->frame_timer + delay) {
1573 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1577 is->frame_timer += delay;
1578 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1579 is->frame_timer = time;
1581 SDL_LockMutex(is->pictq.mutex);
1582 if (!isnan(vp->pts))
1583 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1584 SDL_UnlockMutex(is->pictq.mutex);
1586 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1587 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1588 duration = vp_duration(is, vp, nextvp);
1589 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1590 is->frame_drops_late++;
1591 frame_queue_next(&is->pictq);
1596 if (is->subtitle_st) {
1597 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1598 sp = frame_queue_peek(&is->subpq);
1600 if (frame_queue_nb_remaining(&is->subpq) > 1)
1601 sp2 = frame_queue_peek_next(&is->subpq);
1605 if (sp->serial != is->subtitleq.serial
1606 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1607 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1611 for (i = 0; i < sp->sub.num_rects; i++) {
1612 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1616 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1617 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1618 memset(pixels, 0, sub_rect->w << 2);
1619 SDL_UnlockTexture(is->sub_texture);
1623 frame_queue_next(&is->subpq);
1630 frame_queue_next(&is->pictq);
1631 is->force_refresh = 1;
1633 if (is->step && !is->paused)
1634 stream_toggle_pause(is);
1637 /* display picture */
1638 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1641 is->force_refresh = 0;
1643 static int64_t last_time;
1645 int aqsize, vqsize, sqsize;
1648 cur_time = av_gettime_relative();
1649 if (!last_time || (cur_time - last_time) >= 30000) {
1654 aqsize = is->audioq.size;
1656 vqsize = is->videoq.size;
1657 if (is->subtitle_st)
1658 sqsize = is->subtitleq.size;
1660 if (is->audio_st && is->video_st)
1661 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1662 else if (is->video_st)
1663 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1664 else if (is->audio_st)
1665 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1666 av_log(NULL, AV_LOG_INFO,
1667 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1668 get_master_clock(is),
1669 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1671 is->frame_drops_early + is->frame_drops_late,
1675 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1676 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1678 last_time = cur_time;
1683 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1687 #if defined(DEBUG_SYNC)
1688 printf("frame_type=%c pts=%0.3f\n",
1689 av_get_picture_type_char(src_frame->pict_type), pts);
1692 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1695 vp->sar = src_frame->sample_aspect_ratio;
1698 vp->width = src_frame->width;
1699 vp->height = src_frame->height;
1700 vp->format = src_frame->format;
1703 vp->duration = duration;
1705 vp->serial = serial;
1707 set_default_window_size(vp->width, vp->height, vp->sar);
1709 av_frame_move_ref(vp->frame, src_frame);
1710 frame_queue_push(&is->pictq);
1714 static int get_video_frame(VideoState *is, AVFrame *frame)
1718 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1724 if (frame->pts != AV_NOPTS_VALUE)
1725 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1727 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1729 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1730 if (frame->pts != AV_NOPTS_VALUE) {
1731 double diff = dpts - get_master_clock(is);
1732 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1733 diff - is->frame_last_filter_delay < 0 &&
1734 is->viddec.pkt_serial == is->vidclk.serial &&
1735 is->videoq.nb_packets) {
1736 is->frame_drops_early++;
1737 av_frame_unref(frame);
1748 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1749 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1752 int nb_filters = graph->nb_filters;
1753 AVFilterInOut *outputs = NULL, *inputs = NULL;
1756 outputs = avfilter_inout_alloc();
1757 inputs = avfilter_inout_alloc();
1758 if (!outputs || !inputs) {
1759 ret = AVERROR(ENOMEM);
1763 outputs->name = av_strdup("in");
1764 outputs->filter_ctx = source_ctx;
1765 outputs->pad_idx = 0;
1766 outputs->next = NULL;
1768 inputs->name = av_strdup("out");
1769 inputs->filter_ctx = sink_ctx;
1770 inputs->pad_idx = 0;
1771 inputs->next = NULL;
1773 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1776 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1780 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1781 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1782 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1784 ret = avfilter_graph_config(graph, NULL);
1786 avfilter_inout_free(&outputs);
1787 avfilter_inout_free(&inputs);
1791 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1793 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1794 char sws_flags_str[512] = "";
1795 char buffersrc_args[256];
1797 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1798 AVCodecParameters *codecpar = is->video_st->codecpar;
1799 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1800 AVDictionaryEntry *e = NULL;
1802 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1803 if (!strcmp(e->key, "sws_flags")) {
1804 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1806 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1808 if (strlen(sws_flags_str))
1809 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1811 graph->scale_sws_opts = av_strdup(sws_flags_str);
1813 snprintf(buffersrc_args, sizeof(buffersrc_args),
1814 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1815 frame->width, frame->height, frame->format,
1816 is->video_st->time_base.num, is->video_st->time_base.den,
1817 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1818 if (fr.num && fr.den)
1819 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1821 if ((ret = avfilter_graph_create_filter(&filt_src,
1822 avfilter_get_by_name("buffer"),
1823 "ffplay_buffer", buffersrc_args, NULL,
1827 ret = avfilter_graph_create_filter(&filt_out,
1828 avfilter_get_by_name("buffersink"),
1829 "ffplay_buffersink", NULL, NULL, graph);
1833 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1836 last_filter = filt_out;
1838 /* Note: this macro adds a filter before the lastly added filter, so the
1839 * processing order of the filters is in reverse */
1840 #define INSERT_FILT(name, arg) do { \
1841 AVFilterContext *filt_ctx; \
1843 ret = avfilter_graph_create_filter(&filt_ctx, \
1844 avfilter_get_by_name(name), \
1845 "ffplay_" name, arg, NULL, graph); \
1849 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1853 last_filter = filt_ctx; \
1857 double theta = get_rotation(is->video_st);
1859 if (fabs(theta - 90) < 1.0) {
1860 INSERT_FILT("transpose", "clock");
1861 } else if (fabs(theta - 180) < 1.0) {
1862 INSERT_FILT("hflip", NULL);
1863 INSERT_FILT("vflip", NULL);
1864 } else if (fabs(theta - 270) < 1.0) {
1865 INSERT_FILT("transpose", "cclock");
1866 } else if (fabs(theta) > 1.0) {
1867 char rotate_buf[64];
1868 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1869 INSERT_FILT("rotate", rotate_buf);
1873 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1876 is->in_video_filter = filt_src;
1877 is->out_video_filter = filt_out;
1883 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1885 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1886 int sample_rates[2] = { 0, -1 };
1887 int64_t channel_layouts[2] = { 0, -1 };
1888 int channels[2] = { 0, -1 };
1889 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1890 char aresample_swr_opts[512] = "";
1891 AVDictionaryEntry *e = NULL;
1892 char asrc_args[256];
1895 avfilter_graph_free(&is->agraph);
1896 if (!(is->agraph = avfilter_graph_alloc()))
1897 return AVERROR(ENOMEM);
1899 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1900 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1901 if (strlen(aresample_swr_opts))
1902 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1903 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1905 ret = snprintf(asrc_args, sizeof(asrc_args),
1906 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1907 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1908 is->audio_filter_src.channels,
1909 1, is->audio_filter_src.freq);
1910 if (is->audio_filter_src.channel_layout)
1911 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1912 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1914 ret = avfilter_graph_create_filter(&filt_asrc,
1915 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1916 asrc_args, NULL, is->agraph);
1921 ret = avfilter_graph_create_filter(&filt_asink,
1922 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1923 NULL, NULL, is->agraph);
1927 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1929 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1932 if (force_output_format) {
1933 channel_layouts[0] = is->audio_tgt.channel_layout;
1934 channels [0] = is->audio_tgt.channels;
1935 sample_rates [0] = is->audio_tgt.freq;
1936 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1938 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1940 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1942 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1947 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1950 is->in_audio_filter = filt_asrc;
1951 is->out_audio_filter = filt_asink;
1955 avfilter_graph_free(&is->agraph);
1958 #endif /* CONFIG_AVFILTER */
1960 static int audio_thread(void *arg)
1962 VideoState *is = arg;
1963 AVFrame *frame = av_frame_alloc();
1966 int last_serial = -1;
1967 int64_t dec_channel_layout;
1975 return AVERROR(ENOMEM);
1978 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1982 tb = (AVRational){1, frame->sample_rate};
1985 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
1988 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
1989 frame->format, frame->channels) ||
1990 is->audio_filter_src.channel_layout != dec_channel_layout ||
1991 is->audio_filter_src.freq != frame->sample_rate ||
1992 is->auddec.pkt_serial != last_serial;
1995 char buf1[1024], buf2[1024];
1996 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
1997 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
1998 av_log(NULL, AV_LOG_DEBUG,
1999 "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",
2000 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2001 frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2003 is->audio_filter_src.fmt = frame->format;
2004 is->audio_filter_src.channels = frame->channels;
2005 is->audio_filter_src.channel_layout = dec_channel_layout;
2006 is->audio_filter_src.freq = frame->sample_rate;
2007 last_serial = is->auddec.pkt_serial;
2009 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2013 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2016 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2017 tb = av_buffersink_get_time_base(is->out_audio_filter);
2019 if (!(af = frame_queue_peek_writable(&is->sampq)))
2022 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2023 af->pos = frame->pkt_pos;
2024 af->serial = is->auddec.pkt_serial;
2025 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2027 av_frame_move_ref(af->frame, frame);
2028 frame_queue_push(&is->sampq);
2031 if (is->audioq.serial != is->auddec.pkt_serial)
2034 if (ret == AVERROR_EOF)
2035 is->auddec.finished = is->auddec.pkt_serial;
2038 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2041 avfilter_graph_free(&is->agraph);
2043 av_frame_free(&frame);
2047 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2049 packet_queue_start(d->queue);
2050 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2051 if (!d->decoder_tid) {
2052 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2053 return AVERROR(ENOMEM);
2058 static int video_thread(void *arg)
2060 VideoState *is = arg;
2061 AVFrame *frame = av_frame_alloc();
2065 AVRational tb = is->video_st->time_base;
2066 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2069 AVFilterGraph *graph = avfilter_graph_alloc();
2070 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2073 enum AVPixelFormat last_format = -2;
2074 int last_serial = -1;
2075 int last_vfilter_idx = 0;
2077 av_frame_free(&frame);
2078 return AVERROR(ENOMEM);
2085 avfilter_graph_free(&graph);
2087 return AVERROR(ENOMEM);
2091 ret = get_video_frame(is, frame);
2098 if ( last_w != frame->width
2099 || last_h != frame->height
2100 || last_format != frame->format
2101 || last_serial != is->viddec.pkt_serial
2102 || last_vfilter_idx != is->vfilter_idx) {
2103 av_log(NULL, AV_LOG_DEBUG,
2104 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2106 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2107 frame->width, frame->height,
2108 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2109 avfilter_graph_free(&graph);
2110 graph = avfilter_graph_alloc();
2111 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2113 event.type = FF_QUIT_EVENT;
2114 event.user.data1 = is;
2115 SDL_PushEvent(&event);
2118 filt_in = is->in_video_filter;
2119 filt_out = is->out_video_filter;
2120 last_w = frame->width;
2121 last_h = frame->height;
2122 last_format = frame->format;
2123 last_serial = is->viddec.pkt_serial;
2124 last_vfilter_idx = is->vfilter_idx;
2125 frame_rate = av_buffersink_get_frame_rate(filt_out);
2128 ret = av_buffersrc_add_frame(filt_in, frame);
2133 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2135 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2137 if (ret == AVERROR_EOF)
2138 is->viddec.finished = is->viddec.pkt_serial;
2143 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2144 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2145 is->frame_last_filter_delay = 0;
2146 tb = av_buffersink_get_time_base(filt_out);
2148 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2149 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2150 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
2151 av_frame_unref(frame);
2161 avfilter_graph_free(&graph);
2163 av_frame_free(&frame);
2167 static int subtitle_thread(void *arg)
2169 VideoState *is = arg;
2175 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2178 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2183 if (got_subtitle && sp->sub.format == 0) {
2184 if (sp->sub.pts != AV_NOPTS_VALUE)
2185 pts = sp->sub.pts / (double)AV_TIME_BASE;
2187 sp->serial = is->subdec.pkt_serial;
2188 sp->width = is->subdec.avctx->width;
2189 sp->height = is->subdec.avctx->height;
2192 /* now we can update the picture count */
2193 frame_queue_push(&is->subpq);
2194 } else if (got_subtitle) {
2195 avsubtitle_free(&sp->sub);
2201 /* copy samples for viewing in editor window */
2202 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2206 size = samples_size / sizeof(short);
2208 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2211 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2213 is->sample_array_index += len;
2214 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2215 is->sample_array_index = 0;
2220 /* return the wanted number of samples to get better sync if sync_type is video
2221 * or external master clock */
2222 static int synchronize_audio(VideoState *is, int nb_samples)
2224 int wanted_nb_samples = nb_samples;
2226 /* if not master, then we try to remove or add samples to correct the clock */
2227 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2228 double diff, avg_diff;
2229 int min_nb_samples, max_nb_samples;
2231 diff = get_clock(&is->audclk) - get_master_clock(is);
2233 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2234 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2235 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2236 /* not enough measures to have a correct estimate */
2237 is->audio_diff_avg_count++;
2239 /* estimate the A-V difference */
2240 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2242 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2243 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2244 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2245 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2246 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2248 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2249 diff, avg_diff, wanted_nb_samples - nb_samples,
2250 is->audio_clock, is->audio_diff_threshold);
2253 /* too big difference : may be initial PTS errors, so
2255 is->audio_diff_avg_count = 0;
2256 is->audio_diff_cum = 0;
2260 return wanted_nb_samples;
2264 * Decode one audio frame and return its uncompressed size.
2266 * The processed audio frame is decoded, converted if required, and
2267 * stored in is->audio_buf, with size in bytes given by the return
2270 static int audio_decode_frame(VideoState *is)
2272 int data_size, resampled_data_size;
2273 int64_t dec_channel_layout;
2274 av_unused double audio_clock0;
2275 int wanted_nb_samples;
2283 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2284 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2289 if (!(af = frame_queue_peek_readable(&is->sampq)))
2291 frame_queue_next(&is->sampq);
2292 } while (af->serial != is->audioq.serial);
2294 data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
2295 af->frame->nb_samples,
2296 af->frame->format, 1);
2298 dec_channel_layout =
2299 (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2300 af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
2301 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2303 if (af->frame->format != is->audio_src.fmt ||
2304 dec_channel_layout != is->audio_src.channel_layout ||
2305 af->frame->sample_rate != is->audio_src.freq ||
2306 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2307 swr_free(&is->swr_ctx);
2308 is->swr_ctx = swr_alloc_set_opts(NULL,
2309 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2310 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2312 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2313 av_log(NULL, AV_LOG_ERROR,
2314 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2315 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
2316 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2317 swr_free(&is->swr_ctx);
2320 is->audio_src.channel_layout = dec_channel_layout;
2321 is->audio_src.channels = af->frame->channels;
2322 is->audio_src.freq = af->frame->sample_rate;
2323 is->audio_src.fmt = af->frame->format;
2327 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2328 uint8_t **out = &is->audio_buf1;
2329 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2330 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2333 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2336 if (wanted_nb_samples != af->frame->nb_samples) {
2337 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2338 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2339 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2343 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2344 if (!is->audio_buf1)
2345 return AVERROR(ENOMEM);
2346 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2348 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2351 if (len2 == out_count) {
2352 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2353 if (swr_init(is->swr_ctx) < 0)
2354 swr_free(&is->swr_ctx);
2356 is->audio_buf = is->audio_buf1;
2357 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2359 is->audio_buf = af->frame->data[0];
2360 resampled_data_size = data_size;
2363 audio_clock0 = is->audio_clock;
2364 /* update the audio clock with the pts */
2365 if (!isnan(af->pts))
2366 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2368 is->audio_clock = NAN;
2369 is->audio_clock_serial = af->serial;
2372 static double last_clock;
2373 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2374 is->audio_clock - last_clock,
2375 is->audio_clock, audio_clock0);
2376 last_clock = is->audio_clock;
2379 return resampled_data_size;
2382 /* prepare a new audio buffer */
2383 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2385 VideoState *is = opaque;
2386 int audio_size, len1;
2388 audio_callback_time = av_gettime_relative();
2391 if (is->audio_buf_index >= is->audio_buf_size) {
2392 audio_size = audio_decode_frame(is);
2393 if (audio_size < 0) {
2394 /* if error, just output silence */
2395 is->audio_buf = NULL;
2396 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2398 if (is->show_mode != SHOW_MODE_VIDEO)
2399 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2400 is->audio_buf_size = audio_size;
2402 is->audio_buf_index = 0;
2404 len1 = is->audio_buf_size - is->audio_buf_index;
2407 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2408 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2410 memset(stream, 0, len1);
2411 if (!is->muted && is->audio_buf)
2412 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2416 is->audio_buf_index += len1;
2418 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2419 /* Let's assume the audio driver that is used by SDL has two periods. */
2420 if (!isnan(is->audio_clock)) {
2421 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);
2422 sync_clock_to_slave(&is->extclk, &is->audclk);
2426 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2428 SDL_AudioSpec wanted_spec, spec;
2430 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2431 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2432 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2434 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2436 wanted_nb_channels = atoi(env);
2437 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2439 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2440 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2441 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2443 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2444 wanted_spec.channels = wanted_nb_channels;
2445 wanted_spec.freq = wanted_sample_rate;
2446 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2447 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2450 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2451 next_sample_rate_idx--;
2452 wanted_spec.format = AUDIO_S16SYS;
2453 wanted_spec.silence = 0;
2454 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2455 wanted_spec.callback = sdl_audio_callback;
2456 wanted_spec.userdata = opaque;
2457 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2458 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2459 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2460 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2461 if (!wanted_spec.channels) {
2462 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2463 wanted_spec.channels = wanted_nb_channels;
2464 if (!wanted_spec.freq) {
2465 av_log(NULL, AV_LOG_ERROR,
2466 "No more combinations to try, audio open failed\n");
2470 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2472 if (spec.format != AUDIO_S16SYS) {
2473 av_log(NULL, AV_LOG_ERROR,
2474 "SDL advised audio format %d is not supported!\n", spec.format);
2477 if (spec.channels != wanted_spec.channels) {
2478 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2479 if (!wanted_channel_layout) {
2480 av_log(NULL, AV_LOG_ERROR,
2481 "SDL advised channel count %d is not supported!\n", spec.channels);
2486 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2487 audio_hw_params->freq = spec.freq;
2488 audio_hw_params->channel_layout = wanted_channel_layout;
2489 audio_hw_params->channels = spec.channels;
2490 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2491 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);
2492 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2493 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2499 /* open a given stream. Return 0 if OK */
2500 static int stream_component_open(VideoState *is, int stream_index)
2502 AVFormatContext *ic = is->ic;
2503 AVCodecContext *avctx;
2505 const char *forced_codec_name = NULL;
2506 AVDictionary *opts = NULL;
2507 AVDictionaryEntry *t = NULL;
2508 int sample_rate, nb_channels;
2509 int64_t channel_layout;
2511 int stream_lowres = lowres;
2513 if (stream_index < 0 || stream_index >= ic->nb_streams)
2516 avctx = avcodec_alloc_context3(NULL);
2518 return AVERROR(ENOMEM);
2520 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2523 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2525 codec = avcodec_find_decoder(avctx->codec_id);
2527 switch(avctx->codec_type){
2528 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2529 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2530 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2532 if (forced_codec_name)
2533 codec = avcodec_find_decoder_by_name(forced_codec_name);
2535 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2536 "No codec could be found with name '%s'\n", forced_codec_name);
2537 else av_log(NULL, AV_LOG_WARNING,
2538 "No codec could be found with id %d\n", avctx->codec_id);
2539 ret = AVERROR(EINVAL);
2543 avctx->codec_id = codec->id;
2544 if(stream_lowres > av_codec_get_max_lowres(codec)){
2545 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2546 av_codec_get_max_lowres(codec));
2547 stream_lowres = av_codec_get_max_lowres(codec);
2549 av_codec_set_lowres(avctx, stream_lowres);
2552 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2555 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2557 if(codec->capabilities & AV_CODEC_CAP_DR1)
2558 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2561 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2562 if (!av_dict_get(opts, "threads", NULL, 0))
2563 av_dict_set(&opts, "threads", "auto", 0);
2565 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2566 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2567 av_dict_set(&opts, "refcounted_frames", "1", 0);
2568 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2571 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2572 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2573 ret = AVERROR_OPTION_NOT_FOUND;
2578 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2579 switch (avctx->codec_type) {
2580 case AVMEDIA_TYPE_AUDIO:
2583 AVFilterContext *sink;
2585 is->audio_filter_src.freq = avctx->sample_rate;
2586 is->audio_filter_src.channels = avctx->channels;
2587 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2588 is->audio_filter_src.fmt = avctx->sample_fmt;
2589 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2591 sink = is->out_audio_filter;
2592 sample_rate = av_buffersink_get_sample_rate(sink);
2593 nb_channels = av_buffersink_get_channels(sink);
2594 channel_layout = av_buffersink_get_channel_layout(sink);
2597 sample_rate = avctx->sample_rate;
2598 nb_channels = avctx->channels;
2599 channel_layout = avctx->channel_layout;
2602 /* prepare audio output */
2603 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2605 is->audio_hw_buf_size = ret;
2606 is->audio_src = is->audio_tgt;
2607 is->audio_buf_size = 0;
2608 is->audio_buf_index = 0;
2610 /* init averaging filter */
2611 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2612 is->audio_diff_avg_count = 0;
2613 /* since we do not have a precise anough audio FIFO fullness,
2614 we correct audio sync only if larger than this threshold */
2615 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2617 is->audio_stream = stream_index;
2618 is->audio_st = ic->streams[stream_index];
2620 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2621 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2622 is->auddec.start_pts = is->audio_st->start_time;
2623 is->auddec.start_pts_tb = is->audio_st->time_base;
2625 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2629 case AVMEDIA_TYPE_VIDEO:
2630 is->video_stream = stream_index;
2631 is->video_st = ic->streams[stream_index];
2633 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2634 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2636 is->queue_attachments_req = 1;
2638 case AVMEDIA_TYPE_SUBTITLE:
2639 is->subtitle_stream = stream_index;
2640 is->subtitle_st = ic->streams[stream_index];
2642 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2643 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2652 avcodec_free_context(&avctx);
2654 av_dict_free(&opts);
2659 static int decode_interrupt_cb(void *ctx)
2661 VideoState *is = ctx;
2662 return is->abort_request;
2665 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2666 return stream_id < 0 ||
2667 queue->abort_request ||
2668 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2669 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2672 static int is_realtime(AVFormatContext *s)
2674 if( !strcmp(s->iformat->name, "rtp")
2675 || !strcmp(s->iformat->name, "rtsp")
2676 || !strcmp(s->iformat->name, "sdp")
2680 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2681 || !strncmp(s->filename, "udp:", 4)
2688 /* this thread gets the stream from the disk or the network */
2689 static int read_thread(void *arg)
2691 VideoState *is = arg;
2692 AVFormatContext *ic = NULL;
2694 int st_index[AVMEDIA_TYPE_NB];
2695 AVPacket pkt1, *pkt = &pkt1;
2696 int64_t stream_start_time;
2697 int pkt_in_play_range = 0;
2698 AVDictionaryEntry *t;
2699 SDL_mutex *wait_mutex = SDL_CreateMutex();
2700 int scan_all_pmts_set = 0;
2704 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2705 ret = AVERROR(ENOMEM);
2709 memset(st_index, -1, sizeof(st_index));
2710 is->last_video_stream = is->video_stream = -1;
2711 is->last_audio_stream = is->audio_stream = -1;
2712 is->last_subtitle_stream = is->subtitle_stream = -1;
2715 ic = avformat_alloc_context();
2717 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2718 ret = AVERROR(ENOMEM);
2721 ic->interrupt_callback.callback = decode_interrupt_cb;
2722 ic->interrupt_callback.opaque = is;
2723 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2724 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2725 scan_all_pmts_set = 1;
2727 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2729 print_error(is->filename, err);
2733 if (scan_all_pmts_set)
2734 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2736 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2737 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2738 ret = AVERROR_OPTION_NOT_FOUND;
2744 ic->flags |= AVFMT_FLAG_GENPTS;
2746 av_format_inject_global_side_data(ic);
2748 if (find_stream_info) {
2749 AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
2750 int orig_nb_streams = ic->nb_streams;
2752 err = avformat_find_stream_info(ic, opts);
2754 for (i = 0; i < orig_nb_streams; i++)
2755 av_dict_free(&opts[i]);
2759 av_log(NULL, AV_LOG_WARNING,
2760 "%s: could not find codec parameters\n", is->filename);
2767 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2769 if (seek_by_bytes < 0)
2770 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2772 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2774 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2775 window_title = av_asprintf("%s - %s", t->value, input_filename);
2777 /* if seeking requested, we execute it */
2778 if (start_time != AV_NOPTS_VALUE) {
2781 timestamp = start_time;
2782 /* add the stream start time */
2783 if (ic->start_time != AV_NOPTS_VALUE)
2784 timestamp += ic->start_time;
2785 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2787 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2788 is->filename, (double)timestamp / AV_TIME_BASE);
2792 is->realtime = is_realtime(ic);
2795 av_dump_format(ic, 0, is->filename, 0);
2797 for (i = 0; i < ic->nb_streams; i++) {
2798 AVStream *st = ic->streams[i];
2799 enum AVMediaType type = st->codecpar->codec_type;
2800 st->discard = AVDISCARD_ALL;
2801 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2802 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2805 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2806 if (wanted_stream_spec[i] && st_index[i] == -1) {
2807 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));
2808 st_index[i] = INT_MAX;
2813 st_index[AVMEDIA_TYPE_VIDEO] =
2814 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2815 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2817 st_index[AVMEDIA_TYPE_AUDIO] =
2818 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2819 st_index[AVMEDIA_TYPE_AUDIO],
2820 st_index[AVMEDIA_TYPE_VIDEO],
2822 if (!video_disable && !subtitle_disable)
2823 st_index[AVMEDIA_TYPE_SUBTITLE] =
2824 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2825 st_index[AVMEDIA_TYPE_SUBTITLE],
2826 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2827 st_index[AVMEDIA_TYPE_AUDIO] :
2828 st_index[AVMEDIA_TYPE_VIDEO]),
2831 is->show_mode = show_mode;
2832 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2833 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2834 AVCodecParameters *codecpar = st->codecpar;
2835 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2836 if (codecpar->width)
2837 set_default_window_size(codecpar->width, codecpar->height, sar);
2840 /* open the streams */
2841 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2842 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2846 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2847 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2849 if (is->show_mode == SHOW_MODE_NONE)
2850 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2852 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2853 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2856 if (is->video_stream < 0 && is->audio_stream < 0) {
2857 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2863 if (infinite_buffer < 0 && is->realtime)
2864 infinite_buffer = 1;
2867 if (is->abort_request)
2869 if (is->paused != is->last_paused) {
2870 is->last_paused = is->paused;
2872 is->read_pause_return = av_read_pause(ic);
2876 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2878 (!strcmp(ic->iformat->name, "rtsp") ||
2879 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2880 /* wait 10 ms to avoid trying to get another packet */
2887 int64_t seek_target = is->seek_pos;
2888 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2889 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2890 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2891 // of the seek_pos/seek_rel variables
2893 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2895 av_log(NULL, AV_LOG_ERROR,
2896 "%s: error while seeking\n", is->ic->filename);
2898 if (is->audio_stream >= 0) {
2899 packet_queue_flush(&is->audioq);
2900 packet_queue_put(&is->audioq, &flush_pkt);
2902 if (is->subtitle_stream >= 0) {
2903 packet_queue_flush(&is->subtitleq);
2904 packet_queue_put(&is->subtitleq, &flush_pkt);
2906 if (is->video_stream >= 0) {
2907 packet_queue_flush(&is->videoq);
2908 packet_queue_put(&is->videoq, &flush_pkt);
2910 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2911 set_clock(&is->extclk, NAN, 0);
2913 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2917 is->queue_attachments_req = 1;
2920 step_to_next_frame(is);
2922 if (is->queue_attachments_req) {
2923 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2925 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2927 packet_queue_put(&is->videoq, ©);
2928 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2930 is->queue_attachments_req = 0;
2933 /* if the queue are full, no need to read more */
2934 if (infinite_buffer<1 &&
2935 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2936 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2937 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2938 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2940 SDL_LockMutex(wait_mutex);
2941 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2942 SDL_UnlockMutex(wait_mutex);
2946 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2947 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2948 if (loop != 1 && (!loop || --loop)) {
2949 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2950 } else if (autoexit) {
2955 ret = av_read_frame(ic, pkt);
2957 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
2958 if (is->video_stream >= 0)
2959 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2960 if (is->audio_stream >= 0)
2961 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2962 if (is->subtitle_stream >= 0)
2963 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
2966 if (ic->pb && ic->pb->error)
2968 SDL_LockMutex(wait_mutex);
2969 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2970 SDL_UnlockMutex(wait_mutex);
2975 /* check if packet is in play range specified by user, then queue, otherwise discard */
2976 stream_start_time = ic->streams[pkt->stream_index]->start_time;
2977 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
2978 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2979 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
2980 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2981 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2982 <= ((double)duration / 1000000);
2983 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2984 packet_queue_put(&is->audioq, pkt);
2985 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2986 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
2987 packet_queue_put(&is->videoq, pkt);
2988 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2989 packet_queue_put(&is->subtitleq, pkt);
2991 av_packet_unref(pkt);
2998 avformat_close_input(&ic);
3003 event.type = FF_QUIT_EVENT;
3004 event.user.data1 = is;
3005 SDL_PushEvent(&event);
3007 SDL_DestroyMutex(wait_mutex);
3011 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3015 is = av_mallocz(sizeof(VideoState));
3018 is->filename = av_strdup(filename);
3021 is->iformat = iformat;
3025 /* start video display */
3026 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3028 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3030 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3033 if (packet_queue_init(&is->videoq) < 0 ||
3034 packet_queue_init(&is->audioq) < 0 ||
3035 packet_queue_init(&is->subtitleq) < 0)
3038 if (!(is->continue_read_thread = SDL_CreateCond())) {
3039 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3043 init_clock(&is->vidclk, &is->videoq.serial);
3044 init_clock(&is->audclk, &is->audioq.serial);
3045 init_clock(&is->extclk, &is->extclk.serial);
3046 is->audio_clock_serial = -1;
3047 if (startup_volume < 0)
3048 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3049 if (startup_volume > 100)
3050 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3051 startup_volume = av_clip(startup_volume, 0, 100);
3052 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3053 is->audio_volume = startup_volume;
3055 is->av_sync_type = av_sync_type;
3056 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3057 if (!is->read_tid) {
3058 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3066 static void stream_cycle_channel(VideoState *is, int codec_type)
3068 AVFormatContext *ic = is->ic;
3069 int start_index, stream_index;
3072 AVProgram *p = NULL;
3073 int nb_streams = is->ic->nb_streams;
3075 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3076 start_index = is->last_video_stream;
3077 old_index = is->video_stream;
3078 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3079 start_index = is->last_audio_stream;
3080 old_index = is->audio_stream;
3082 start_index = is->last_subtitle_stream;
3083 old_index = is->subtitle_stream;
3085 stream_index = start_index;
3087 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3088 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3090 nb_streams = p->nb_stream_indexes;
3091 for (start_index = 0; start_index < nb_streams; start_index++)
3092 if (p->stream_index[start_index] == stream_index)
3094 if (start_index == nb_streams)
3096 stream_index = start_index;
3101 if (++stream_index >= nb_streams)
3103 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3106 is->last_subtitle_stream = -1;
3109 if (start_index == -1)
3113 if (stream_index == start_index)
3115 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3116 if (st->codecpar->codec_type == codec_type) {
3117 /* check that parameters are OK */
3118 switch (codec_type) {
3119 case AVMEDIA_TYPE_AUDIO:
3120 if (st->codecpar->sample_rate != 0 &&
3121 st->codecpar->channels != 0)
3124 case AVMEDIA_TYPE_VIDEO:
3125 case AVMEDIA_TYPE_SUBTITLE:
3133 if (p && stream_index != -1)
3134 stream_index = p->stream_index[stream_index];
3135 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3136 av_get_media_type_string(codec_type),
3140 stream_component_close(is, old_index);
3141 stream_component_open(is, stream_index);
3145 static void toggle_full_screen(VideoState *is)
3147 is_full_screen = !is_full_screen;
3148 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3151 static void toggle_audio_display(VideoState *is)
3153 int next = is->show_mode;
3155 next = (next + 1) % SHOW_MODE_NB;
3156 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3157 if (is->show_mode != next) {
3158 is->force_refresh = 1;
3159 is->show_mode = next;
3163 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3164 double remaining_time = 0.0;
3166 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3167 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3171 if (remaining_time > 0.0)
3172 av_usleep((int64_t)(remaining_time * 1000000.0));
3173 remaining_time = REFRESH_RATE;
3174 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3175 video_refresh(is, &remaining_time);
3180 static void seek_chapter(VideoState *is, int incr)
3182 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3185 if (!is->ic->nb_chapters)
3188 /* find the current chapter */
3189 for (i = 0; i < is->ic->nb_chapters; i++) {
3190 AVChapter *ch = is->ic->chapters[i];
3191 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3199 if (i >= is->ic->nb_chapters)
3202 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3203 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3204 AV_TIME_BASE_Q), 0, 0);
3207 /* handle an event sent by the GUI */
3208 static void event_loop(VideoState *cur_stream)
3211 double incr, pos, frac;
3215 refresh_loop_wait_event(cur_stream, &event);
3216 switch (event.type) {
3218 if (exit_on_keydown) {
3219 do_exit(cur_stream);
3222 switch (event.key.keysym.sym) {
3225 do_exit(cur_stream);
3228 toggle_full_screen(cur_stream);
3229 cur_stream->force_refresh = 1;
3233 toggle_pause(cur_stream);
3236 toggle_mute(cur_stream);
3238 case SDLK_KP_MULTIPLY:
3240 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3242 case SDLK_KP_DIVIDE:
3244 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3246 case SDLK_s: // S: Step to next frame
3247 step_to_next_frame(cur_stream);
3250 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3253 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3256 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3257 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3258 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3261 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3265 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3266 if (++cur_stream->vfilter_idx >= nb_vfilters)
3267 cur_stream->vfilter_idx = 0;
3269 cur_stream->vfilter_idx = 0;
3270 toggle_audio_display(cur_stream);
3273 toggle_audio_display(cur_stream);
3277 if (cur_stream->ic->nb_chapters <= 1) {
3281 seek_chapter(cur_stream, 1);
3284 if (cur_stream->ic->nb_chapters <= 1) {
3288 seek_chapter(cur_stream, -1);
3302 if (seek_by_bytes) {
3304 if (pos < 0 && cur_stream->video_stream >= 0)
3305 pos = frame_queue_last_pos(&cur_stream->pictq);
3306 if (pos < 0 && cur_stream->audio_stream >= 0)
3307 pos = frame_queue_last_pos(&cur_stream->sampq);
3309 pos = avio_tell(cur_stream->ic->pb);
3310 if (cur_stream->ic->bit_rate)
3311 incr *= cur_stream->ic->bit_rate / 8.0;
3315 stream_seek(cur_stream, pos, incr, 1);
3317 pos = get_master_clock(cur_stream);
3319 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3321 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3322 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3323 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3330 case SDL_MOUSEBUTTONDOWN:
3331 if (exit_on_mousedown) {
3332 do_exit(cur_stream);
3335 if (event.button.button == SDL_BUTTON_LEFT) {
3336 static int64_t last_mouse_left_click = 0;
3337 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3338 toggle_full_screen(cur_stream);
3339 cur_stream->force_refresh = 1;
3340 last_mouse_left_click = 0;
3342 last_mouse_left_click = av_gettime_relative();
3345 case SDL_MOUSEMOTION:
3346 if (cursor_hidden) {
3350 cursor_last_shown = av_gettime_relative();
3351 if (event.type == SDL_MOUSEBUTTONDOWN) {
3352 if (event.button.button != SDL_BUTTON_RIGHT)
3356 if (!(event.motion.state & SDL_BUTTON_RMASK))
3360 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3361 uint64_t size = avio_size(cur_stream->ic->pb);
3362 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3366 int tns, thh, tmm, tss;
3367 tns = cur_stream->ic->duration / 1000000LL;
3369 tmm = (tns % 3600) / 60;
3371 frac = x / cur_stream->width;
3374 mm = (ns % 3600) / 60;
3376 av_log(NULL, AV_LOG_INFO,
3377 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3378 hh, mm, ss, thh, tmm, tss);
3379 ts = frac * cur_stream->ic->duration;
3380 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3381 ts += cur_stream->ic->start_time;
3382 stream_seek(cur_stream, ts, 0, 0);
3385 case SDL_WINDOWEVENT:
3386 switch (event.window.event) {
3387 case SDL_WINDOWEVENT_RESIZED:
3388 screen_width = cur_stream->width = event.window.data1;
3389 screen_height = cur_stream->height = event.window.data2;
3390 if (cur_stream->vis_texture) {
3391 SDL_DestroyTexture(cur_stream->vis_texture);
3392 cur_stream->vis_texture = NULL;
3394 case SDL_WINDOWEVENT_EXPOSED:
3395 cur_stream->force_refresh = 1;
3400 do_exit(cur_stream);
3408 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3410 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3411 return opt_default(NULL, "video_size", arg);
3414 static int opt_width(void *optctx, const char *opt, const char *arg)
3416 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3420 static int opt_height(void *optctx, const char *opt, const char *arg)
3422 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3426 static int opt_format(void *optctx, const char *opt, const char *arg)
3428 file_iformat = av_find_input_format(arg);
3429 if (!file_iformat) {
3430 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3431 return AVERROR(EINVAL);
3436 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3438 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3439 return opt_default(NULL, "pixel_format", arg);
3442 static int opt_sync(void *optctx, const char *opt, const char *arg)
3444 if (!strcmp(arg, "audio"))
3445 av_sync_type = AV_SYNC_AUDIO_MASTER;
3446 else if (!strcmp(arg, "video"))
3447 av_sync_type = AV_SYNC_VIDEO_MASTER;
3448 else if (!strcmp(arg, "ext"))
3449 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3451 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3457 static int opt_seek(void *optctx, const char *opt, const char *arg)
3459 start_time = parse_time_or_die(opt, arg, 1);
3463 static int opt_duration(void *optctx, const char *opt, const char *arg)
3465 duration = parse_time_or_die(opt, arg, 1);
3469 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3471 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3472 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3473 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3474 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3478 static void opt_input_file(void *optctx, const char *filename)
3480 if (input_filename) {
3481 av_log(NULL, AV_LOG_FATAL,
3482 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3483 filename, input_filename);
3486 if (!strcmp(filename, "-"))
3488 input_filename = filename;
3491 static int opt_codec(void *optctx, const char *opt, const char *arg)
3493 const char *spec = strchr(opt, ':');
3495 av_log(NULL, AV_LOG_ERROR,
3496 "No media specifier was specified in '%s' in option '%s'\n",
3498 return AVERROR(EINVAL);
3502 case 'a' : audio_codec_name = arg; break;
3503 case 's' : subtitle_codec_name = arg; break;
3504 case 'v' : video_codec_name = arg; break;
3506 av_log(NULL, AV_LOG_ERROR,
3507 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3508 return AVERROR(EINVAL);
3515 static const OptionDef options[] = {
3516 CMDUTILS_COMMON_OPTIONS
3517 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3518 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3519 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3520 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3521 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3522 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3523 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3524 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3525 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3526 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3527 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3528 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3529 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3530 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3531 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3532 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3533 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3534 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3535 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3536 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3537 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3538 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3539 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3540 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3541 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3542 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3543 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3544 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3545 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3546 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3547 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3549 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3550 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3552 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3553 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3554 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3555 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3556 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3557 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3558 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3559 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3560 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3561 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3562 "read and decode the streams to fill missing information with heuristics" },
3566 static void show_usage(void)
3568 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3569 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3570 av_log(NULL, AV_LOG_INFO, "\n");
3573 void show_help_default(const char *opt, const char *arg)
3575 av_log_set_callback(log_callback_help);
3577 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3578 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3580 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3581 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3582 #if !CONFIG_AVFILTER
3583 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3585 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3587 printf("\nWhile playing:\n"
3589 "f toggle full screen\n"
3592 "9, 0 decrease and increase volume respectively\n"
3593 "/, * decrease and increase volume respectively\n"
3594 "a cycle audio channel in the current program\n"
3595 "v cycle video channel\n"
3596 "t cycle subtitle channel in the current program\n"
3598 "w cycle video filters or show modes\n"
3599 "s activate frame-step mode\n"
3600 "left/right seek backward/forward 10 seconds\n"
3601 "down/up seek backward/forward 1 minute\n"
3602 "page down/page up seek backward/forward 10 minutes\n"
3603 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3604 "left double-click toggle full screen\n"
3608 static int lockmgr(void **mtx, enum AVLockOp op)
3611 case AV_LOCK_CREATE:
3612 *mtx = SDL_CreateMutex();
3614 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3618 case AV_LOCK_OBTAIN:
3619 return !!SDL_LockMutex(*mtx);
3620 case AV_LOCK_RELEASE:
3621 return !!SDL_UnlockMutex(*mtx);
3622 case AV_LOCK_DESTROY:
3623 SDL_DestroyMutex(*mtx);
3629 /* Called from the main */
3630 int main(int argc, char **argv)
3637 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3638 parse_loglevel(argc, argv, options);
3640 /* register all codecs, demux and protocols */
3642 avdevice_register_all();
3645 avfilter_register_all();
3648 avformat_network_init();
3652 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3653 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3655 show_banner(argc, argv, options);
3657 parse_options(NULL, argc, argv, options, opt_input_file);
3659 if (!input_filename) {
3661 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3662 av_log(NULL, AV_LOG_FATAL,
3663 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3667 if (display_disable) {
3670 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3672 flags &= ~SDL_INIT_AUDIO;
3674 /* Try to work around an occasional ALSA buffer underflow issue when the
3675 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3676 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3677 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3679 if (display_disable)
3680 flags &= ~SDL_INIT_VIDEO;
3681 if (SDL_Init (flags)) {
3682 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3683 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3687 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3688 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3690 if (av_lockmgr_register(lockmgr)) {
3691 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3695 av_init_packet(&flush_pkt);
3696 flush_pkt.data = (uint8_t *)&flush_pkt;
3698 is = stream_open(input_filename, file_iformat);
3700 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");