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 */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
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 */
171 typedef struct FrameQueue {
172 Frame queue[FRAME_QUEUE_SIZE];
185 AV_SYNC_AUDIO_MASTER, /* default choice */
186 AV_SYNC_VIDEO_MASTER,
187 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
190 typedef struct Decoder {
194 AVCodecContext *avctx;
198 SDL_cond *empty_queue_cond;
200 AVRational start_pts_tb;
202 AVRational next_pts_tb;
203 SDL_Thread *decoder_tid;
206 typedef struct VideoState {
207 SDL_Thread *read_tid;
208 AVInputFormat *iformat;
213 int queue_attachments_req;
218 int read_pause_return;
239 int audio_clock_serial;
240 double audio_diff_cum; /* used for AV difference average computation */
241 double audio_diff_avg_coef;
242 double audio_diff_threshold;
243 int audio_diff_avg_count;
246 int audio_hw_buf_size;
249 unsigned int audio_buf_size; /* in bytes */
250 unsigned int audio_buf1_size;
251 int audio_buf_index; /* in bytes */
252 int audio_write_buf_size;
255 struct AudioParams audio_src;
257 struct AudioParams audio_filter_src;
259 struct AudioParams audio_tgt;
260 struct SwrContext *swr_ctx;
261 int frame_drops_early;
262 int frame_drops_late;
265 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
267 int16_t sample_array[SAMPLE_ARRAY_SIZE];
268 int sample_array_index;
272 FFTSample *rdft_data;
274 double last_vis_time;
275 SDL_Texture *vis_texture;
276 SDL_Texture *sub_texture;
279 AVStream *subtitle_st;
280 PacketQueue subtitleq;
283 double frame_last_returned_time;
284 double frame_last_filter_delay;
288 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
289 struct SwsContext *img_convert_ctx;
290 struct SwsContext *sub_convert_ctx;
294 int width, height, xleft, ytop;
299 AVFilterContext *in_video_filter; // the first filter in the video chain
300 AVFilterContext *out_video_filter; // the last filter in the video chain
301 AVFilterContext *in_audio_filter; // the first filter in the audio chain
302 AVFilterContext *out_audio_filter; // the last filter in the audio chain
303 AVFilterGraph *agraph; // audio filter graph
306 int last_video_stream, last_audio_stream, last_subtitle_stream;
308 SDL_cond *continue_read_thread;
311 /* options specified by the user */
312 static AVInputFormat *file_iformat;
313 static const char *input_filename;
314 static const char *window_title;
315 static int default_width = 640;
316 static int default_height = 480;
317 static int screen_width = 0;
318 static int screen_height = 0;
319 static int audio_disable;
320 static int video_disable;
321 static int subtitle_disable;
322 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
323 static int seek_by_bytes = -1;
324 static int display_disable;
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;
353 /* current context */
354 static int is_full_screen;
355 static int64_t audio_callback_time;
357 static AVPacket flush_pkt;
359 #define FF_ALLOC_EVENT (SDL_USEREVENT)
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 void free_picture(Frame *vp);
396 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
398 MyAVPacketList *pkt1;
400 if (q->abort_request)
403 pkt1 = av_malloc(sizeof(MyAVPacketList));
408 if (pkt == &flush_pkt)
410 pkt1->serial = q->serial;
415 q->last_pkt->next = pkt1;
418 q->size += pkt1->pkt.size + sizeof(*pkt1);
419 q->duration += pkt1->pkt.duration;
420 /* XXX: should duplicate packet data in DV case */
421 SDL_CondSignal(q->cond);
425 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
429 SDL_LockMutex(q->mutex);
430 ret = packet_queue_put_private(q, pkt);
431 SDL_UnlockMutex(q->mutex);
433 if (pkt != &flush_pkt && ret < 0)
434 av_packet_unref(pkt);
439 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
441 AVPacket pkt1, *pkt = &pkt1;
445 pkt->stream_index = stream_index;
446 return packet_queue_put(q, pkt);
449 /* packet queue handling */
450 static int packet_queue_init(PacketQueue *q)
452 memset(q, 0, sizeof(PacketQueue));
453 q->mutex = SDL_CreateMutex();
455 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
456 return AVERROR(ENOMEM);
458 q->cond = SDL_CreateCond();
460 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
461 return AVERROR(ENOMEM);
463 q->abort_request = 1;
467 static void packet_queue_flush(PacketQueue *q)
469 MyAVPacketList *pkt, *pkt1;
471 SDL_LockMutex(q->mutex);
472 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
474 av_packet_unref(&pkt->pkt);
482 SDL_UnlockMutex(q->mutex);
485 static void packet_queue_destroy(PacketQueue *q)
487 packet_queue_flush(q);
488 SDL_DestroyMutex(q->mutex);
489 SDL_DestroyCond(q->cond);
492 static void packet_queue_abort(PacketQueue *q)
494 SDL_LockMutex(q->mutex);
496 q->abort_request = 1;
498 SDL_CondSignal(q->cond);
500 SDL_UnlockMutex(q->mutex);
503 static void packet_queue_start(PacketQueue *q)
505 SDL_LockMutex(q->mutex);
506 q->abort_request = 0;
507 packet_queue_put_private(q, &flush_pkt);
508 SDL_UnlockMutex(q->mutex);
511 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
512 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
514 MyAVPacketList *pkt1;
517 SDL_LockMutex(q->mutex);
520 if (q->abort_request) {
527 q->first_pkt = pkt1->next;
531 q->size -= pkt1->pkt.size + sizeof(*pkt1);
532 q->duration -= pkt1->pkt.duration;
535 *serial = pkt1->serial;
543 SDL_CondWait(q->cond, q->mutex);
546 SDL_UnlockMutex(q->mutex);
550 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
551 memset(d, 0, sizeof(Decoder));
554 d->empty_queue_cond = empty_queue_cond;
555 d->start_pts = AV_NOPTS_VALUE;
558 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
564 if (d->queue->abort_request)
567 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
570 if (d->queue->nb_packets == 0)
571 SDL_CondSignal(d->empty_queue_cond);
572 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
574 if (pkt.data == flush_pkt.data) {
575 avcodec_flush_buffers(d->avctx);
577 d->next_pts = d->start_pts;
578 d->next_pts_tb = d->start_pts_tb;
580 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
581 av_packet_unref(&d->pkt);
582 d->pkt_temp = d->pkt = pkt;
583 d->packet_pending = 1;
586 switch (d->avctx->codec_type) {
587 case AVMEDIA_TYPE_VIDEO:
588 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
590 if (decoder_reorder_pts == -1) {
591 frame->pts = av_frame_get_best_effort_timestamp(frame);
592 } else if (!decoder_reorder_pts) {
593 frame->pts = frame->pkt_dts;
597 case AVMEDIA_TYPE_AUDIO:
598 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
600 AVRational tb = (AVRational){1, frame->sample_rate};
601 if (frame->pts != AV_NOPTS_VALUE)
602 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
603 else if (d->next_pts != AV_NOPTS_VALUE)
604 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
605 if (frame->pts != AV_NOPTS_VALUE) {
606 d->next_pts = frame->pts + frame->nb_samples;
611 case AVMEDIA_TYPE_SUBTITLE:
612 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
617 d->packet_pending = 0;
620 d->pkt_temp.pts = AV_NOPTS_VALUE;
621 if (d->pkt_temp.data) {
622 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
623 ret = d->pkt_temp.size;
624 d->pkt_temp.data += ret;
625 d->pkt_temp.size -= ret;
626 if (d->pkt_temp.size <= 0)
627 d->packet_pending = 0;
630 d->packet_pending = 0;
631 d->finished = d->pkt_serial;
635 } while (!got_frame && !d->finished);
640 static void decoder_destroy(Decoder *d) {
641 av_packet_unref(&d->pkt);
642 avcodec_free_context(&d->avctx);
645 static void frame_queue_unref_item(Frame *vp)
647 av_frame_unref(vp->frame);
648 avsubtitle_free(&vp->sub);
651 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
654 memset(f, 0, sizeof(FrameQueue));
655 if (!(f->mutex = SDL_CreateMutex())) {
656 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
657 return AVERROR(ENOMEM);
659 if (!(f->cond = SDL_CreateCond())) {
660 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
661 return AVERROR(ENOMEM);
664 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
665 f->keep_last = !!keep_last;
666 for (i = 0; i < f->max_size; i++)
667 if (!(f->queue[i].frame = av_frame_alloc()))
668 return AVERROR(ENOMEM);
672 static void frame_queue_destory(FrameQueue *f)
675 for (i = 0; i < f->max_size; i++) {
676 Frame *vp = &f->queue[i];
677 frame_queue_unref_item(vp);
678 av_frame_free(&vp->frame);
681 SDL_DestroyMutex(f->mutex);
682 SDL_DestroyCond(f->cond);
685 static void frame_queue_signal(FrameQueue *f)
687 SDL_LockMutex(f->mutex);
688 SDL_CondSignal(f->cond);
689 SDL_UnlockMutex(f->mutex);
692 static Frame *frame_queue_peek(FrameQueue *f)
694 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
697 static Frame *frame_queue_peek_next(FrameQueue *f)
699 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
702 static Frame *frame_queue_peek_last(FrameQueue *f)
704 return &f->queue[f->rindex];
707 static Frame *frame_queue_peek_writable(FrameQueue *f)
709 /* wait until we have space to put a new frame */
710 SDL_LockMutex(f->mutex);
711 while (f->size >= f->max_size &&
712 !f->pktq->abort_request) {
713 SDL_CondWait(f->cond, f->mutex);
715 SDL_UnlockMutex(f->mutex);
717 if (f->pktq->abort_request)
720 return &f->queue[f->windex];
723 static Frame *frame_queue_peek_readable(FrameQueue *f)
725 /* wait until we have a readable a new frame */
726 SDL_LockMutex(f->mutex);
727 while (f->size - f->rindex_shown <= 0 &&
728 !f->pktq->abort_request) {
729 SDL_CondWait(f->cond, f->mutex);
731 SDL_UnlockMutex(f->mutex);
733 if (f->pktq->abort_request)
736 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
739 static void frame_queue_push(FrameQueue *f)
741 if (++f->windex == f->max_size)
743 SDL_LockMutex(f->mutex);
745 SDL_CondSignal(f->cond);
746 SDL_UnlockMutex(f->mutex);
749 static void frame_queue_next(FrameQueue *f)
751 if (f->keep_last && !f->rindex_shown) {
755 frame_queue_unref_item(&f->queue[f->rindex]);
756 if (++f->rindex == f->max_size)
758 SDL_LockMutex(f->mutex);
760 SDL_CondSignal(f->cond);
761 SDL_UnlockMutex(f->mutex);
764 /* return the number of undisplayed frames in the queue */
765 static int frame_queue_nb_remaining(FrameQueue *f)
767 return f->size - f->rindex_shown;
770 /* return last shown position */
771 static int64_t frame_queue_last_pos(FrameQueue *f)
773 Frame *fp = &f->queue[f->rindex];
774 if (f->rindex_shown && fp->serial == f->pktq->serial)
780 static void decoder_abort(Decoder *d, FrameQueue *fq)
782 packet_queue_abort(d->queue);
783 frame_queue_signal(fq);
784 SDL_WaitThread(d->decoder_tid, NULL);
785 d->decoder_tid = NULL;
786 packet_queue_flush(d->queue);
789 static inline void fill_rectangle(int x, int y, int w, int h)
797 SDL_RenderFillRect(renderer, &rect);
800 static void free_picture(Frame *vp)
803 SDL_DestroyTexture(vp->bmp);
808 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
812 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
815 SDL_DestroyTexture(*texture);
816 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
818 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
821 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
823 memset(pixels, 0, pitch * new_height);
824 SDL_UnlockTexture(*texture);
830 static void calculate_display_rect(SDL_Rect *rect,
831 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
832 int pic_width, int pic_height, AVRational pic_sar)
835 int width, height, x, y;
837 if (pic_sar.num == 0)
840 aspect_ratio = av_q2d(pic_sar);
842 if (aspect_ratio <= 0.0)
844 aspect_ratio *= (float)pic_width / (float)pic_height;
846 /* XXX: we suppose the screen has a 1.0 pixel ratio */
848 width = lrint(height * aspect_ratio) & ~1;
849 if (width > scr_width) {
851 height = lrint(width / aspect_ratio) & ~1;
853 x = (scr_width - width) / 2;
854 y = (scr_height - height) / 2;
855 rect->x = scr_xleft + x;
856 rect->y = scr_ytop + y;
857 rect->w = FFMAX(width, 1);
858 rect->h = FFMAX(height, 1);
861 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
863 switch (frame->format) {
864 case AV_PIX_FMT_YUV420P:
865 if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
866 av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
869 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
870 frame->data[1], frame->linesize[1],
871 frame->data[2], frame->linesize[2]);
873 case AV_PIX_FMT_BGRA:
874 if (frame->linesize[0] < 0) {
875 ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
877 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
881 /* This should only happen if we are not using avfilter... */
882 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
883 frame->width, frame->height, frame->format, frame->width, frame->height,
884 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
885 if (*img_convert_ctx != NULL) {
888 if (!SDL_LockTexture(tex, NULL, (void **)&pixels, &pitch)) {
889 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
890 0, frame->height, &pixels, &pitch);
891 SDL_UnlockTexture(tex);
894 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
902 static void video_image_display(VideoState *is)
908 vp = frame_queue_peek_last(&is->pictq);
910 if (is->subtitle_st) {
911 if (frame_queue_nb_remaining(&is->subpq) > 0) {
912 sp = frame_queue_peek(&is->subpq);
914 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
919 if (!sp->width || !sp->height) {
920 sp->width = vp->width;
921 sp->height = vp->height;
923 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
926 for (i = 0; i < sp->sub.num_rects; i++) {
927 AVSubtitleRect *sub_rect = sp->sub.rects[i];
929 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
930 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
931 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
932 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
934 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
935 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
936 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
937 0, NULL, NULL, NULL);
938 if (!is->sub_convert_ctx) {
939 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
942 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
943 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
944 0, sub_rect->h, &pixels, &pitch);
945 SDL_UnlockTexture(is->sub_texture);
955 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
958 if (upload_texture(vp->bmp, vp->frame, &is->img_convert_ctx) < 0)
961 vp->flip_v = vp->frame->linesize[0] < 0;
964 SDL_RenderCopyEx(renderer, vp->bmp, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
966 #if USE_ONEPASS_SUBTITLE_RENDER
967 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
970 double xratio = (double)rect.w / (double)sp->width;
971 double yratio = (double)rect.h / (double)sp->height;
972 for (i = 0; i < sp->sub.num_rects; i++) {
973 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
974 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
975 .y = rect.y + sub_rect->y * yratio,
976 .w = sub_rect->w * xratio,
977 .h = sub_rect->h * yratio};
978 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
985 static inline int compute_mod(int a, int b)
987 return a < 0 ? a%b + b : a%b;
990 static void video_audio_display(VideoState *s)
992 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
993 int ch, channels, h, h2;
995 int rdft_bits, nb_freq;
997 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
999 nb_freq = 1 << (rdft_bits - 1);
1001 /* compute display index : center on currently output samples */
1002 channels = s->audio_tgt.channels;
1003 nb_display_channels = channels;
1005 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1007 delay = s->audio_write_buf_size;
1010 /* to be more precise, we take into account the time spent since
1011 the last buffer computation */
1012 if (audio_callback_time) {
1013 time_diff = av_gettime_relative() - audio_callback_time;
1014 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1017 delay += 2 * data_used;
1018 if (delay < data_used)
1021 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1022 if (s->show_mode == SHOW_MODE_WAVES) {
1024 for (i = 0; i < 1000; i += channels) {
1025 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1026 int a = s->sample_array[idx];
1027 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1028 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1029 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1031 if (h < score && (b ^ c) < 0) {
1038 s->last_i_start = i_start;
1040 i_start = s->last_i_start;
1043 if (s->show_mode == SHOW_MODE_WAVES) {
1044 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1046 /* total height for one channel */
1047 h = s->height / nb_display_channels;
1048 /* graph height / 2 */
1050 for (ch = 0; ch < nb_display_channels; ch++) {
1052 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1053 for (x = 0; x < s->width; x++) {
1054 y = (s->sample_array[i] * h2) >> 15;
1061 fill_rectangle(s->xleft + x, ys, 1, y);
1063 if (i >= SAMPLE_ARRAY_SIZE)
1064 i -= SAMPLE_ARRAY_SIZE;
1068 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1070 for (ch = 1; ch < nb_display_channels; ch++) {
1071 y = s->ytop + ch * h;
1072 fill_rectangle(s->xleft, y, s->width, 1);
1075 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1078 nb_display_channels= FFMIN(nb_display_channels, 2);
1079 if (rdft_bits != s->rdft_bits) {
1080 av_rdft_end(s->rdft);
1081 av_free(s->rdft_data);
1082 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1083 s->rdft_bits = rdft_bits;
1084 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1086 if (!s->rdft || !s->rdft_data){
1087 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1088 s->show_mode = SHOW_MODE_WAVES;
1091 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1094 for (ch = 0; ch < nb_display_channels; ch++) {
1095 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1097 for (x = 0; x < 2 * nb_freq; x++) {
1098 double w = (x-nb_freq) * (1.0 / nb_freq);
1099 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1101 if (i >= SAMPLE_ARRAY_SIZE)
1102 i -= SAMPLE_ARRAY_SIZE;
1104 av_rdft_calc(s->rdft, data[ch]);
1106 /* Least efficient way to do this, we should of course
1107 * directly access it but it is more than fast enough. */
1108 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1110 pixels += pitch * s->height;
1111 for (y = 0; y < s->height; y++) {
1112 double w = 1 / sqrt(nb_freq);
1113 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]));
1114 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1119 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1121 SDL_UnlockTexture(s->vis_texture);
1123 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1127 if (s->xpos >= s->width)
1132 static void stream_component_close(VideoState *is, int stream_index)
1134 AVFormatContext *ic = is->ic;
1135 AVCodecParameters *codecpar;
1137 if (stream_index < 0 || stream_index >= ic->nb_streams)
1139 codecpar = ic->streams[stream_index]->codecpar;
1141 switch (codecpar->codec_type) {
1142 case AVMEDIA_TYPE_AUDIO:
1143 decoder_abort(&is->auddec, &is->sampq);
1145 decoder_destroy(&is->auddec);
1146 swr_free(&is->swr_ctx);
1147 av_freep(&is->audio_buf1);
1148 is->audio_buf1_size = 0;
1149 is->audio_buf = NULL;
1152 av_rdft_end(is->rdft);
1153 av_freep(&is->rdft_data);
1158 case AVMEDIA_TYPE_VIDEO:
1159 decoder_abort(&is->viddec, &is->pictq);
1160 decoder_destroy(&is->viddec);
1162 case AVMEDIA_TYPE_SUBTITLE:
1163 decoder_abort(&is->subdec, &is->subpq);
1164 decoder_destroy(&is->subdec);
1170 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1171 switch (codecpar->codec_type) {
1172 case AVMEDIA_TYPE_AUDIO:
1173 is->audio_st = NULL;
1174 is->audio_stream = -1;
1176 case AVMEDIA_TYPE_VIDEO:
1177 is->video_st = NULL;
1178 is->video_stream = -1;
1180 case AVMEDIA_TYPE_SUBTITLE:
1181 is->subtitle_st = NULL;
1182 is->subtitle_stream = -1;
1189 static void stream_close(VideoState *is)
1191 /* XXX: use a special url_shutdown call to abort parse cleanly */
1192 is->abort_request = 1;
1193 SDL_WaitThread(is->read_tid, NULL);
1195 /* close each stream */
1196 if (is->audio_stream >= 0)
1197 stream_component_close(is, is->audio_stream);
1198 if (is->video_stream >= 0)
1199 stream_component_close(is, is->video_stream);
1200 if (is->subtitle_stream >= 0)
1201 stream_component_close(is, is->subtitle_stream);
1203 avformat_close_input(&is->ic);
1205 packet_queue_destroy(&is->videoq);
1206 packet_queue_destroy(&is->audioq);
1207 packet_queue_destroy(&is->subtitleq);
1209 /* free all pictures */
1210 frame_queue_destory(&is->pictq);
1211 frame_queue_destory(&is->sampq);
1212 frame_queue_destory(&is->subpq);
1213 SDL_DestroyCond(is->continue_read_thread);
1214 sws_freeContext(is->img_convert_ctx);
1215 sws_freeContext(is->sub_convert_ctx);
1216 av_free(is->filename);
1217 if (is->vis_texture)
1218 SDL_DestroyTexture(is->vis_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, Frame *vp)
1263 if (vp && vp->width)
1264 set_default_window_size(vp->width, vp->height, vp->sar);
1275 int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
1277 window_title = input_filename;
1279 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1280 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1281 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1283 SDL_RendererInfo info;
1284 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1286 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1287 renderer = SDL_CreateRenderer(window, -1, 0);
1290 if (!SDL_GetRendererInfo(renderer, &info))
1291 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1295 SDL_SetWindowSize(window, w, h);
1298 if (!window || !renderer) {
1299 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1309 /* display the current picture, if any */
1310 static void video_display(VideoState *is)
1313 video_open(is, NULL);
1315 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1316 SDL_RenderClear(renderer);
1317 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1318 video_audio_display(is);
1319 else if (is->video_st)
1320 video_image_display(is);
1321 SDL_RenderPresent(renderer);
1324 static double get_clock(Clock *c)
1326 if (*c->queue_serial != c->serial)
1331 double time = av_gettime_relative() / 1000000.0;
1332 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1336 static void set_clock_at(Clock *c, double pts, int serial, double time)
1339 c->last_updated = time;
1340 c->pts_drift = c->pts - time;
1344 static void set_clock(Clock *c, double pts, int serial)
1346 double time = av_gettime_relative() / 1000000.0;
1347 set_clock_at(c, pts, serial, time);
1350 static void set_clock_speed(Clock *c, double speed)
1352 set_clock(c, get_clock(c), c->serial);
1356 static void init_clock(Clock *c, int *queue_serial)
1360 c->queue_serial = queue_serial;
1361 set_clock(c, NAN, -1);
1364 static void sync_clock_to_slave(Clock *c, Clock *slave)
1366 double clock = get_clock(c);
1367 double slave_clock = get_clock(slave);
1368 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1369 set_clock(c, slave_clock, slave->serial);
1372 static int get_master_sync_type(VideoState *is) {
1373 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1375 return AV_SYNC_VIDEO_MASTER;
1377 return AV_SYNC_AUDIO_MASTER;
1378 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1380 return AV_SYNC_AUDIO_MASTER;
1382 return AV_SYNC_EXTERNAL_CLOCK;
1384 return AV_SYNC_EXTERNAL_CLOCK;
1388 /* get the current master clock value */
1389 static double get_master_clock(VideoState *is)
1393 switch (get_master_sync_type(is)) {
1394 case AV_SYNC_VIDEO_MASTER:
1395 val = get_clock(&is->vidclk);
1397 case AV_SYNC_AUDIO_MASTER:
1398 val = get_clock(&is->audclk);
1401 val = get_clock(&is->extclk);
1407 static void check_external_clock_speed(VideoState *is) {
1408 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1409 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1410 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1411 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1412 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1413 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1415 double speed = is->extclk.speed;
1417 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1421 /* seek in the stream */
1422 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1424 if (!is->seek_req) {
1427 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1429 is->seek_flags |= AVSEEK_FLAG_BYTE;
1431 SDL_CondSignal(is->continue_read_thread);
1435 /* pause or resume the video */
1436 static void stream_toggle_pause(VideoState *is)
1439 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1440 if (is->read_pause_return != AVERROR(ENOSYS)) {
1441 is->vidclk.paused = 0;
1443 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1445 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1446 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1449 static void toggle_pause(VideoState *is)
1451 stream_toggle_pause(is);
1455 static void toggle_mute(VideoState *is)
1457 is->muted = !is->muted;
1460 static void update_volume(VideoState *is, int sign, int step)
1462 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1465 static void step_to_next_frame(VideoState *is)
1467 /* if the stream is paused unpause it, then step */
1469 stream_toggle_pause(is);
1473 static double compute_target_delay(double delay, VideoState *is)
1475 double sync_threshold, diff = 0;
1477 /* update delay to follow master synchronisation source */
1478 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1479 /* if video is slave, we try to correct big delays by
1480 duplicating or deleting a frame */
1481 diff = get_clock(&is->vidclk) - get_master_clock(is);
1483 /* skip or repeat frame. We take into account the
1484 delay to compute the threshold. I still don't know
1485 if it is the best guess */
1486 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1487 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1488 if (diff <= -sync_threshold)
1489 delay = FFMAX(0, delay + diff);
1490 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1491 delay = delay + diff;
1492 else if (diff >= sync_threshold)
1497 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1503 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1504 if (vp->serial == nextvp->serial) {
1505 double duration = nextvp->pts - vp->pts;
1506 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1507 return vp->duration;
1515 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1516 /* update current video pts */
1517 set_clock(&is->vidclk, pts, serial);
1518 sync_clock_to_slave(&is->extclk, &is->vidclk);
1521 /* called to display each frame */
1522 static void video_refresh(void *opaque, double *remaining_time)
1524 VideoState *is = opaque;
1529 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1530 check_external_clock_speed(is);
1532 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1533 time = av_gettime_relative() / 1000000.0;
1534 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1536 is->last_vis_time = time;
1538 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1543 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1544 // nothing to do, no picture to display in the queue
1546 double last_duration, duration, delay;
1549 /* dequeue the picture */
1550 lastvp = frame_queue_peek_last(&is->pictq);
1551 vp = frame_queue_peek(&is->pictq);
1553 if (vp->serial != is->videoq.serial) {
1554 frame_queue_next(&is->pictq);
1558 if (lastvp->serial != vp->serial)
1559 is->frame_timer = av_gettime_relative() / 1000000.0;
1564 /* compute nominal last_duration */
1565 last_duration = vp_duration(is, lastvp, vp);
1566 delay = compute_target_delay(last_duration, is);
1568 time= av_gettime_relative()/1000000.0;
1569 if (time < is->frame_timer + delay) {
1570 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1574 is->frame_timer += delay;
1575 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1576 is->frame_timer = time;
1578 SDL_LockMutex(is->pictq.mutex);
1579 if (!isnan(vp->pts))
1580 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1581 SDL_UnlockMutex(is->pictq.mutex);
1583 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1584 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1585 duration = vp_duration(is, vp, nextvp);
1586 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1587 is->frame_drops_late++;
1588 frame_queue_next(&is->pictq);
1593 if (is->subtitle_st) {
1594 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1595 sp = frame_queue_peek(&is->subpq);
1597 if (frame_queue_nb_remaining(&is->subpq) > 1)
1598 sp2 = frame_queue_peek_next(&is->subpq);
1602 if (sp->serial != is->subtitleq.serial
1603 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1604 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1608 for (i = 0; i < sp->sub.num_rects; i++) {
1609 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1613 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1614 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1615 memset(pixels, 0, sub_rect->w << 2);
1616 SDL_UnlockTexture(is->sub_texture);
1620 frame_queue_next(&is->subpq);
1627 frame_queue_next(&is->pictq);
1628 is->force_refresh = 1;
1630 if (is->step && !is->paused)
1631 stream_toggle_pause(is);
1634 /* display picture */
1635 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1638 is->force_refresh = 0;
1640 static int64_t last_time;
1642 int aqsize, vqsize, sqsize;
1645 cur_time = av_gettime_relative();
1646 if (!last_time || (cur_time - last_time) >= 30000) {
1651 aqsize = is->audioq.size;
1653 vqsize = is->videoq.size;
1654 if (is->subtitle_st)
1655 sqsize = is->subtitleq.size;
1657 if (is->audio_st && is->video_st)
1658 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1659 else if (is->video_st)
1660 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1661 else if (is->audio_st)
1662 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1663 av_log(NULL, AV_LOG_INFO,
1664 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1665 get_master_clock(is),
1666 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1668 is->frame_drops_early + is->frame_drops_late,
1672 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1673 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1675 last_time = cur_time;
1680 /* allocate a picture (needs to do that in main thread to avoid
1681 potential locking problems */
1682 static void alloc_picture(VideoState *is)
1687 vp = &is->pictq.queue[is->pictq.windex];
1691 if (vp->format == AV_PIX_FMT_YUV420P)
1692 sdl_format = SDL_PIXELFORMAT_YV12;
1694 sdl_format = SDL_PIXELFORMAT_ARGB8888;
1696 if (realloc_texture(&vp->bmp, sdl_format, vp->width, vp->height, SDL_BLENDMODE_NONE, 0) < 0) {
1697 /* SDL allocates a buffer smaller than requested if the video
1698 * overlay hardware is unable to support the requested size. */
1699 av_log(NULL, AV_LOG_FATAL,
1700 "Error: the video system does not support an image\n"
1701 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1702 "to reduce the image size.\n", vp->width, vp->height );
1706 SDL_LockMutex(is->pictq.mutex);
1708 SDL_CondSignal(is->pictq.cond);
1709 SDL_UnlockMutex(is->pictq.mutex);
1712 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1716 #if defined(DEBUG_SYNC)
1717 printf("frame_type=%c pts=%0.3f\n",
1718 av_get_picture_type_char(src_frame->pict_type), pts);
1721 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1724 vp->sar = src_frame->sample_aspect_ratio;
1727 /* alloc or resize hardware picture buffer */
1728 if (!vp->bmp || !vp->allocated ||
1729 vp->width != src_frame->width ||
1730 vp->height != src_frame->height ||
1731 vp->format != src_frame->format) {
1735 vp->width = src_frame->width;
1736 vp->height = src_frame->height;
1737 vp->format = src_frame->format;
1739 /* the allocation must be done in the main thread to avoid
1740 locking problems. */
1741 event.type = FF_ALLOC_EVENT;
1742 event.user.data1 = is;
1743 SDL_PushEvent(&event);
1745 /* wait until the picture is allocated */
1746 SDL_LockMutex(is->pictq.mutex);
1747 while (!vp->allocated && !is->videoq.abort_request) {
1748 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1750 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1751 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, FF_ALLOC_EVENT, FF_ALLOC_EVENT) != 1) {
1752 while (!vp->allocated && !is->abort_request) {
1753 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1756 SDL_UnlockMutex(is->pictq.mutex);
1758 if (is->videoq.abort_request)
1762 /* if the frame is not skipped, then display it */
1765 vp->duration = duration;
1767 vp->serial = serial;
1769 av_frame_move_ref(vp->frame, src_frame);
1770 frame_queue_push(&is->pictq);
1775 static int get_video_frame(VideoState *is, AVFrame *frame)
1779 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1785 if (frame->pts != AV_NOPTS_VALUE)
1786 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1788 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1790 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1791 if (frame->pts != AV_NOPTS_VALUE) {
1792 double diff = dpts - get_master_clock(is);
1793 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1794 diff - is->frame_last_filter_delay < 0 &&
1795 is->viddec.pkt_serial == is->vidclk.serial &&
1796 is->videoq.nb_packets) {
1797 is->frame_drops_early++;
1798 av_frame_unref(frame);
1809 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1810 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1813 int nb_filters = graph->nb_filters;
1814 AVFilterInOut *outputs = NULL, *inputs = NULL;
1817 outputs = avfilter_inout_alloc();
1818 inputs = avfilter_inout_alloc();
1819 if (!outputs || !inputs) {
1820 ret = AVERROR(ENOMEM);
1824 outputs->name = av_strdup("in");
1825 outputs->filter_ctx = source_ctx;
1826 outputs->pad_idx = 0;
1827 outputs->next = NULL;
1829 inputs->name = av_strdup("out");
1830 inputs->filter_ctx = sink_ctx;
1831 inputs->pad_idx = 0;
1832 inputs->next = NULL;
1834 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1837 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1841 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1842 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1843 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1845 ret = avfilter_graph_config(graph, NULL);
1847 avfilter_inout_free(&outputs);
1848 avfilter_inout_free(&inputs);
1852 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1854 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1855 char sws_flags_str[512] = "";
1856 char buffersrc_args[256];
1858 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1859 AVCodecParameters *codecpar = is->video_st->codecpar;
1860 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1861 AVDictionaryEntry *e = NULL;
1863 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1864 if (!strcmp(e->key, "sws_flags")) {
1865 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1867 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1869 if (strlen(sws_flags_str))
1870 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1872 graph->scale_sws_opts = av_strdup(sws_flags_str);
1874 snprintf(buffersrc_args, sizeof(buffersrc_args),
1875 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1876 frame->width, frame->height, frame->format,
1877 is->video_st->time_base.num, is->video_st->time_base.den,
1878 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1879 if (fr.num && fr.den)
1880 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1882 if ((ret = avfilter_graph_create_filter(&filt_src,
1883 avfilter_get_by_name("buffer"),
1884 "ffplay_buffer", buffersrc_args, NULL,
1888 ret = avfilter_graph_create_filter(&filt_out,
1889 avfilter_get_by_name("buffersink"),
1890 "ffplay_buffersink", NULL, NULL, graph);
1894 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1897 last_filter = filt_out;
1899 /* Note: this macro adds a filter before the lastly added filter, so the
1900 * processing order of the filters is in reverse */
1901 #define INSERT_FILT(name, arg) do { \
1902 AVFilterContext *filt_ctx; \
1904 ret = avfilter_graph_create_filter(&filt_ctx, \
1905 avfilter_get_by_name(name), \
1906 "ffplay_" name, arg, NULL, graph); \
1910 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1914 last_filter = filt_ctx; \
1918 double theta = get_rotation(is->video_st);
1920 if (fabs(theta - 90) < 1.0) {
1921 INSERT_FILT("transpose", "clock");
1922 } else if (fabs(theta - 180) < 1.0) {
1923 INSERT_FILT("hflip", NULL);
1924 INSERT_FILT("vflip", NULL);
1925 } else if (fabs(theta - 270) < 1.0) {
1926 INSERT_FILT("transpose", "cclock");
1927 } else if (fabs(theta) > 1.0) {
1928 char rotate_buf[64];
1929 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1930 INSERT_FILT("rotate", rotate_buf);
1934 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1937 is->in_video_filter = filt_src;
1938 is->out_video_filter = filt_out;
1944 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1946 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1947 int sample_rates[2] = { 0, -1 };
1948 int64_t channel_layouts[2] = { 0, -1 };
1949 int channels[2] = { 0, -1 };
1950 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1951 char aresample_swr_opts[512] = "";
1952 AVDictionaryEntry *e = NULL;
1953 char asrc_args[256];
1956 avfilter_graph_free(&is->agraph);
1957 if (!(is->agraph = avfilter_graph_alloc()))
1958 return AVERROR(ENOMEM);
1960 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1961 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1962 if (strlen(aresample_swr_opts))
1963 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1964 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1966 ret = snprintf(asrc_args, sizeof(asrc_args),
1967 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1968 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1969 is->audio_filter_src.channels,
1970 1, is->audio_filter_src.freq);
1971 if (is->audio_filter_src.channel_layout)
1972 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1973 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1975 ret = avfilter_graph_create_filter(&filt_asrc,
1976 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1977 asrc_args, NULL, is->agraph);
1982 ret = avfilter_graph_create_filter(&filt_asink,
1983 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1984 NULL, NULL, is->agraph);
1988 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1990 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1993 if (force_output_format) {
1994 channel_layouts[0] = is->audio_tgt.channel_layout;
1995 channels [0] = is->audio_tgt.channels;
1996 sample_rates [0] = is->audio_tgt.freq;
1997 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1999 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2001 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2003 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2008 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2011 is->in_audio_filter = filt_asrc;
2012 is->out_audio_filter = filt_asink;
2016 avfilter_graph_free(&is->agraph);
2019 #endif /* CONFIG_AVFILTER */
2021 static int audio_thread(void *arg)
2023 VideoState *is = arg;
2024 AVFrame *frame = av_frame_alloc();
2027 int last_serial = -1;
2028 int64_t dec_channel_layout;
2036 return AVERROR(ENOMEM);
2039 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2043 tb = (AVRational){1, frame->sample_rate};
2046 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2049 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2050 frame->format, av_frame_get_channels(frame)) ||
2051 is->audio_filter_src.channel_layout != dec_channel_layout ||
2052 is->audio_filter_src.freq != frame->sample_rate ||
2053 is->auddec.pkt_serial != last_serial;
2056 char buf1[1024], buf2[1024];
2057 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2058 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2059 av_log(NULL, AV_LOG_DEBUG,
2060 "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
2061 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2062 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2064 is->audio_filter_src.fmt = frame->format;
2065 is->audio_filter_src.channels = av_frame_get_channels(frame);
2066 is->audio_filter_src.channel_layout = dec_channel_layout;
2067 is->audio_filter_src.freq = frame->sample_rate;
2068 last_serial = is->auddec.pkt_serial;
2070 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2074 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2077 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2078 tb = is->out_audio_filter->inputs[0]->time_base;
2080 if (!(af = frame_queue_peek_writable(&is->sampq)))
2083 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2084 af->pos = av_frame_get_pkt_pos(frame);
2085 af->serial = is->auddec.pkt_serial;
2086 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2088 av_frame_move_ref(af->frame, frame);
2089 frame_queue_push(&is->sampq);
2092 if (is->audioq.serial != is->auddec.pkt_serial)
2095 if (ret == AVERROR_EOF)
2096 is->auddec.finished = is->auddec.pkt_serial;
2099 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2102 avfilter_graph_free(&is->agraph);
2104 av_frame_free(&frame);
2108 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2110 packet_queue_start(d->queue);
2111 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2112 if (!d->decoder_tid) {
2113 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2114 return AVERROR(ENOMEM);
2119 static int video_thread(void *arg)
2121 VideoState *is = arg;
2122 AVFrame *frame = av_frame_alloc();
2126 AVRational tb = is->video_st->time_base;
2127 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2130 AVFilterGraph *graph = avfilter_graph_alloc();
2131 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2134 enum AVPixelFormat last_format = -2;
2135 int last_serial = -1;
2136 int last_vfilter_idx = 0;
2138 av_frame_free(&frame);
2139 return AVERROR(ENOMEM);
2146 avfilter_graph_free(&graph);
2148 return AVERROR(ENOMEM);
2152 ret = get_video_frame(is, frame);
2159 if ( last_w != frame->width
2160 || last_h != frame->height
2161 || last_format != frame->format
2162 || last_serial != is->viddec.pkt_serial
2163 || last_vfilter_idx != is->vfilter_idx) {
2164 av_log(NULL, AV_LOG_DEBUG,
2165 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2167 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2168 frame->width, frame->height,
2169 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2170 avfilter_graph_free(&graph);
2171 graph = avfilter_graph_alloc();
2172 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2174 event.type = FF_QUIT_EVENT;
2175 event.user.data1 = is;
2176 SDL_PushEvent(&event);
2179 filt_in = is->in_video_filter;
2180 filt_out = is->out_video_filter;
2181 last_w = frame->width;
2182 last_h = frame->height;
2183 last_format = frame->format;
2184 last_serial = is->viddec.pkt_serial;
2185 last_vfilter_idx = is->vfilter_idx;
2186 frame_rate = filt_out->inputs[0]->frame_rate;
2189 ret = av_buffersrc_add_frame(filt_in, frame);
2194 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2196 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2198 if (ret == AVERROR_EOF)
2199 is->viddec.finished = is->viddec.pkt_serial;
2204 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2205 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2206 is->frame_last_filter_delay = 0;
2207 tb = filt_out->inputs[0]->time_base;
2209 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2210 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2211 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2212 av_frame_unref(frame);
2222 avfilter_graph_free(&graph);
2224 av_frame_free(&frame);
2228 static int subtitle_thread(void *arg)
2230 VideoState *is = arg;
2236 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2239 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2244 if (got_subtitle && sp->sub.format == 0) {
2245 if (sp->sub.pts != AV_NOPTS_VALUE)
2246 pts = sp->sub.pts / (double)AV_TIME_BASE;
2248 sp->serial = is->subdec.pkt_serial;
2249 sp->width = is->subdec.avctx->width;
2250 sp->height = is->subdec.avctx->height;
2253 /* now we can update the picture count */
2254 frame_queue_push(&is->subpq);
2255 } else if (got_subtitle) {
2256 avsubtitle_free(&sp->sub);
2262 /* copy samples for viewing in editor window */
2263 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2267 size = samples_size / sizeof(short);
2269 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2272 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2274 is->sample_array_index += len;
2275 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2276 is->sample_array_index = 0;
2281 /* return the wanted number of samples to get better sync if sync_type is video
2282 * or external master clock */
2283 static int synchronize_audio(VideoState *is, int nb_samples)
2285 int wanted_nb_samples = nb_samples;
2287 /* if not master, then we try to remove or add samples to correct the clock */
2288 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2289 double diff, avg_diff;
2290 int min_nb_samples, max_nb_samples;
2292 diff = get_clock(&is->audclk) - get_master_clock(is);
2294 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2295 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2296 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2297 /* not enough measures to have a correct estimate */
2298 is->audio_diff_avg_count++;
2300 /* estimate the A-V difference */
2301 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2303 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2304 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2305 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2306 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2307 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2309 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2310 diff, avg_diff, wanted_nb_samples - nb_samples,
2311 is->audio_clock, is->audio_diff_threshold);
2314 /* too big difference : may be initial PTS errors, so
2316 is->audio_diff_avg_count = 0;
2317 is->audio_diff_cum = 0;
2321 return wanted_nb_samples;
2325 * Decode one audio frame and return its uncompressed size.
2327 * The processed audio frame is decoded, converted if required, and
2328 * stored in is->audio_buf, with size in bytes given by the return
2331 static int audio_decode_frame(VideoState *is)
2333 int data_size, resampled_data_size;
2334 int64_t dec_channel_layout;
2335 av_unused double audio_clock0;
2336 int wanted_nb_samples;
2344 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2345 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2350 if (!(af = frame_queue_peek_readable(&is->sampq)))
2352 frame_queue_next(&is->sampq);
2353 } while (af->serial != is->audioq.serial);
2355 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2356 af->frame->nb_samples,
2357 af->frame->format, 1);
2359 dec_channel_layout =
2360 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2361 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2362 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2364 if (af->frame->format != is->audio_src.fmt ||
2365 dec_channel_layout != is->audio_src.channel_layout ||
2366 af->frame->sample_rate != is->audio_src.freq ||
2367 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2368 swr_free(&is->swr_ctx);
2369 is->swr_ctx = swr_alloc_set_opts(NULL,
2370 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2371 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2373 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2374 av_log(NULL, AV_LOG_ERROR,
2375 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2376 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2377 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2378 swr_free(&is->swr_ctx);
2381 is->audio_src.channel_layout = dec_channel_layout;
2382 is->audio_src.channels = av_frame_get_channels(af->frame);
2383 is->audio_src.freq = af->frame->sample_rate;
2384 is->audio_src.fmt = af->frame->format;
2388 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2389 uint8_t **out = &is->audio_buf1;
2390 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2391 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2394 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2397 if (wanted_nb_samples != af->frame->nb_samples) {
2398 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2399 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2400 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2404 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2405 if (!is->audio_buf1)
2406 return AVERROR(ENOMEM);
2407 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2409 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2412 if (len2 == out_count) {
2413 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2414 if (swr_init(is->swr_ctx) < 0)
2415 swr_free(&is->swr_ctx);
2417 is->audio_buf = is->audio_buf1;
2418 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2420 is->audio_buf = af->frame->data[0];
2421 resampled_data_size = data_size;
2424 audio_clock0 = is->audio_clock;
2425 /* update the audio clock with the pts */
2426 if (!isnan(af->pts))
2427 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2429 is->audio_clock = NAN;
2430 is->audio_clock_serial = af->serial;
2433 static double last_clock;
2434 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2435 is->audio_clock - last_clock,
2436 is->audio_clock, audio_clock0);
2437 last_clock = is->audio_clock;
2440 return resampled_data_size;
2443 /* prepare a new audio buffer */
2444 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2446 VideoState *is = opaque;
2447 int audio_size, len1;
2449 audio_callback_time = av_gettime_relative();
2452 if (is->audio_buf_index >= is->audio_buf_size) {
2453 audio_size = audio_decode_frame(is);
2454 if (audio_size < 0) {
2455 /* if error, just output silence */
2456 is->audio_buf = NULL;
2457 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2459 if (is->show_mode != SHOW_MODE_VIDEO)
2460 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2461 is->audio_buf_size = audio_size;
2463 is->audio_buf_index = 0;
2465 len1 = is->audio_buf_size - is->audio_buf_index;
2468 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2469 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2471 memset(stream, 0, len1);
2472 if (!is->muted && is->audio_buf)
2473 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2477 is->audio_buf_index += len1;
2479 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2480 /* Let's assume the audio driver that is used by SDL has two periods. */
2481 if (!isnan(is->audio_clock)) {
2482 set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
2483 sync_clock_to_slave(&is->extclk, &is->audclk);
2487 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2489 SDL_AudioSpec wanted_spec, spec;
2491 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2492 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2493 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2495 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2497 wanted_nb_channels = atoi(env);
2498 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2500 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2501 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2502 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2504 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2505 wanted_spec.channels = wanted_nb_channels;
2506 wanted_spec.freq = wanted_sample_rate;
2507 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2508 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2511 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2512 next_sample_rate_idx--;
2513 wanted_spec.format = AUDIO_S16SYS;
2514 wanted_spec.silence = 0;
2515 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2516 wanted_spec.callback = sdl_audio_callback;
2517 wanted_spec.userdata = opaque;
2518 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2519 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2520 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2521 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2522 if (!wanted_spec.channels) {
2523 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2524 wanted_spec.channels = wanted_nb_channels;
2525 if (!wanted_spec.freq) {
2526 av_log(NULL, AV_LOG_ERROR,
2527 "No more combinations to try, audio open failed\n");
2531 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2533 if (spec.format != AUDIO_S16SYS) {
2534 av_log(NULL, AV_LOG_ERROR,
2535 "SDL advised audio format %d is not supported!\n", spec.format);
2538 if (spec.channels != wanted_spec.channels) {
2539 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2540 if (!wanted_channel_layout) {
2541 av_log(NULL, AV_LOG_ERROR,
2542 "SDL advised channel count %d is not supported!\n", spec.channels);
2547 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2548 audio_hw_params->freq = spec.freq;
2549 audio_hw_params->channel_layout = wanted_channel_layout;
2550 audio_hw_params->channels = spec.channels;
2551 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2552 audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
2553 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2554 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2560 /* open a given stream. Return 0 if OK */
2561 static int stream_component_open(VideoState *is, int stream_index)
2563 AVFormatContext *ic = is->ic;
2564 AVCodecContext *avctx;
2566 const char *forced_codec_name = NULL;
2567 AVDictionary *opts = NULL;
2568 AVDictionaryEntry *t = NULL;
2569 int sample_rate, nb_channels;
2570 int64_t channel_layout;
2572 int stream_lowres = lowres;
2574 if (stream_index < 0 || stream_index >= ic->nb_streams)
2577 avctx = avcodec_alloc_context3(NULL);
2579 return AVERROR(ENOMEM);
2581 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2584 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2586 codec = avcodec_find_decoder(avctx->codec_id);
2588 switch(avctx->codec_type){
2589 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2590 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2591 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2593 if (forced_codec_name)
2594 codec = avcodec_find_decoder_by_name(forced_codec_name);
2596 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2597 "No codec could be found with name '%s'\n", forced_codec_name);
2598 else av_log(NULL, AV_LOG_WARNING,
2599 "No codec could be found with id %d\n", avctx->codec_id);
2600 ret = AVERROR(EINVAL);
2604 avctx->codec_id = codec->id;
2605 if(stream_lowres > av_codec_get_max_lowres(codec)){
2606 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2607 av_codec_get_max_lowres(codec));
2608 stream_lowres = av_codec_get_max_lowres(codec);
2610 av_codec_set_lowres(avctx, stream_lowres);
2613 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2616 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2618 if(codec->capabilities & AV_CODEC_CAP_DR1)
2619 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2622 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2623 if (!av_dict_get(opts, "threads", NULL, 0))
2624 av_dict_set(&opts, "threads", "auto", 0);
2626 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2627 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2628 av_dict_set(&opts, "refcounted_frames", "1", 0);
2629 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2632 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2633 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2634 ret = AVERROR_OPTION_NOT_FOUND;
2639 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2640 switch (avctx->codec_type) {
2641 case AVMEDIA_TYPE_AUDIO:
2646 is->audio_filter_src.freq = avctx->sample_rate;
2647 is->audio_filter_src.channels = avctx->channels;
2648 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2649 is->audio_filter_src.fmt = avctx->sample_fmt;
2650 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2652 link = is->out_audio_filter->inputs[0];
2653 sample_rate = link->sample_rate;
2654 nb_channels = avfilter_link_get_channels(link);
2655 channel_layout = link->channel_layout;
2658 sample_rate = avctx->sample_rate;
2659 nb_channels = avctx->channels;
2660 channel_layout = avctx->channel_layout;
2663 /* prepare audio output */
2664 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2666 is->audio_hw_buf_size = ret;
2667 is->audio_src = is->audio_tgt;
2668 is->audio_buf_size = 0;
2669 is->audio_buf_index = 0;
2671 /* init averaging filter */
2672 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2673 is->audio_diff_avg_count = 0;
2674 /* since we do not have a precise anough audio FIFO fullness,
2675 we correct audio sync only if larger than this threshold */
2676 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2678 is->audio_stream = stream_index;
2679 is->audio_st = ic->streams[stream_index];
2681 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2682 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2683 is->auddec.start_pts = is->audio_st->start_time;
2684 is->auddec.start_pts_tb = is->audio_st->time_base;
2686 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2690 case AVMEDIA_TYPE_VIDEO:
2691 is->video_stream = stream_index;
2692 is->video_st = ic->streams[stream_index];
2694 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2695 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2697 is->queue_attachments_req = 1;
2699 case AVMEDIA_TYPE_SUBTITLE:
2700 is->subtitle_stream = stream_index;
2701 is->subtitle_st = ic->streams[stream_index];
2703 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2704 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2713 avcodec_free_context(&avctx);
2715 av_dict_free(&opts);
2720 static int decode_interrupt_cb(void *ctx)
2722 VideoState *is = ctx;
2723 return is->abort_request;
2726 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2727 return stream_id < 0 ||
2728 queue->abort_request ||
2729 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2730 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2733 static int is_realtime(AVFormatContext *s)
2735 if( !strcmp(s->iformat->name, "rtp")
2736 || !strcmp(s->iformat->name, "rtsp")
2737 || !strcmp(s->iformat->name, "sdp")
2741 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2742 || !strncmp(s->filename, "udp:", 4)
2749 /* this thread gets the stream from the disk or the network */
2750 static int read_thread(void *arg)
2752 VideoState *is = arg;
2753 AVFormatContext *ic = NULL;
2755 int st_index[AVMEDIA_TYPE_NB];
2756 AVPacket pkt1, *pkt = &pkt1;
2757 int64_t stream_start_time;
2758 int pkt_in_play_range = 0;
2759 AVDictionaryEntry *t;
2760 AVDictionary **opts;
2761 int orig_nb_streams;
2762 SDL_mutex *wait_mutex = SDL_CreateMutex();
2763 int scan_all_pmts_set = 0;
2767 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2768 ret = AVERROR(ENOMEM);
2772 memset(st_index, -1, sizeof(st_index));
2773 is->last_video_stream = is->video_stream = -1;
2774 is->last_audio_stream = is->audio_stream = -1;
2775 is->last_subtitle_stream = is->subtitle_stream = -1;
2778 ic = avformat_alloc_context();
2780 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2781 ret = AVERROR(ENOMEM);
2784 ic->interrupt_callback.callback = decode_interrupt_cb;
2785 ic->interrupt_callback.opaque = is;
2786 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2787 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2788 scan_all_pmts_set = 1;
2790 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2792 print_error(is->filename, err);
2796 if (scan_all_pmts_set)
2797 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2799 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2800 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2801 ret = AVERROR_OPTION_NOT_FOUND;
2807 ic->flags |= AVFMT_FLAG_GENPTS;
2809 av_format_inject_global_side_data(ic);
2811 opts = setup_find_stream_info_opts(ic, codec_opts);
2812 orig_nb_streams = ic->nb_streams;
2814 err = avformat_find_stream_info(ic, opts);
2816 for (i = 0; i < orig_nb_streams; i++)
2817 av_dict_free(&opts[i]);
2821 av_log(NULL, AV_LOG_WARNING,
2822 "%s: could not find codec parameters\n", is->filename);
2828 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2830 if (seek_by_bytes < 0)
2831 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2833 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2835 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2836 window_title = av_asprintf("%s - %s", t->value, input_filename);
2838 /* if seeking requested, we execute it */
2839 if (start_time != AV_NOPTS_VALUE) {
2842 timestamp = start_time;
2843 /* add the stream start time */
2844 if (ic->start_time != AV_NOPTS_VALUE)
2845 timestamp += ic->start_time;
2846 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2848 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2849 is->filename, (double)timestamp / AV_TIME_BASE);
2853 is->realtime = is_realtime(ic);
2856 av_dump_format(ic, 0, is->filename, 0);
2858 for (i = 0; i < ic->nb_streams; i++) {
2859 AVStream *st = ic->streams[i];
2860 enum AVMediaType type = st->codecpar->codec_type;
2861 st->discard = AVDISCARD_ALL;
2862 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2863 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2866 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2867 if (wanted_stream_spec[i] && st_index[i] == -1) {
2868 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));
2869 st_index[i] = INT_MAX;
2874 st_index[AVMEDIA_TYPE_VIDEO] =
2875 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2876 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2878 st_index[AVMEDIA_TYPE_AUDIO] =
2879 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2880 st_index[AVMEDIA_TYPE_AUDIO],
2881 st_index[AVMEDIA_TYPE_VIDEO],
2883 if (!video_disable && !subtitle_disable)
2884 st_index[AVMEDIA_TYPE_SUBTITLE] =
2885 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2886 st_index[AVMEDIA_TYPE_SUBTITLE],
2887 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2888 st_index[AVMEDIA_TYPE_AUDIO] :
2889 st_index[AVMEDIA_TYPE_VIDEO]),
2892 is->show_mode = show_mode;
2893 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2894 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2895 AVCodecParameters *codecpar = st->codecpar;
2896 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2897 if (codecpar->width)
2898 set_default_window_size(codecpar->width, codecpar->height, sar);
2901 /* open the streams */
2902 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2903 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2907 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2908 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2910 if (is->show_mode == SHOW_MODE_NONE)
2911 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2913 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2914 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2917 if (is->video_stream < 0 && is->audio_stream < 0) {
2918 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2924 if (infinite_buffer < 0 && is->realtime)
2925 infinite_buffer = 1;
2928 if (is->abort_request)
2930 if (is->paused != is->last_paused) {
2931 is->last_paused = is->paused;
2933 is->read_pause_return = av_read_pause(ic);
2937 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2939 (!strcmp(ic->iformat->name, "rtsp") ||
2940 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2941 /* wait 10 ms to avoid trying to get another packet */
2948 int64_t seek_target = is->seek_pos;
2949 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2950 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2951 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2952 // of the seek_pos/seek_rel variables
2954 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2956 av_log(NULL, AV_LOG_ERROR,
2957 "%s: error while seeking\n", is->ic->filename);
2959 if (is->audio_stream >= 0) {
2960 packet_queue_flush(&is->audioq);
2961 packet_queue_put(&is->audioq, &flush_pkt);
2963 if (is->subtitle_stream >= 0) {
2964 packet_queue_flush(&is->subtitleq);
2965 packet_queue_put(&is->subtitleq, &flush_pkt);
2967 if (is->video_stream >= 0) {
2968 packet_queue_flush(&is->videoq);
2969 packet_queue_put(&is->videoq, &flush_pkt);
2971 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2972 set_clock(&is->extclk, NAN, 0);
2974 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2978 is->queue_attachments_req = 1;
2981 step_to_next_frame(is);
2983 if (is->queue_attachments_req) {
2984 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2986 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2988 packet_queue_put(&is->videoq, ©);
2989 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2991 is->queue_attachments_req = 0;
2994 /* if the queue are full, no need to read more */
2995 if (infinite_buffer<1 &&
2996 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2997 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2998 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2999 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
3001 SDL_LockMutex(wait_mutex);
3002 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3003 SDL_UnlockMutex(wait_mutex);
3007 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3008 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3009 if (loop != 1 && (!loop || --loop)) {
3010 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3011 } else if (autoexit) {
3016 ret = av_read_frame(ic, pkt);
3018 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3019 if (is->video_stream >= 0)
3020 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3021 if (is->audio_stream >= 0)
3022 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3023 if (is->subtitle_stream >= 0)
3024 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3027 if (ic->pb && ic->pb->error)
3029 SDL_LockMutex(wait_mutex);
3030 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3031 SDL_UnlockMutex(wait_mutex);
3036 /* check if packet is in play range specified by user, then queue, otherwise discard */
3037 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3038 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3039 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3040 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3041 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3042 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3043 <= ((double)duration / 1000000);
3044 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3045 packet_queue_put(&is->audioq, pkt);
3046 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3047 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3048 packet_queue_put(&is->videoq, pkt);
3049 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3050 packet_queue_put(&is->subtitleq, pkt);
3052 av_packet_unref(pkt);
3059 avformat_close_input(&ic);
3064 event.type = FF_QUIT_EVENT;
3065 event.user.data1 = is;
3066 SDL_PushEvent(&event);
3068 SDL_DestroyMutex(wait_mutex);
3072 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3076 is = av_mallocz(sizeof(VideoState));
3079 is->filename = av_strdup(filename);
3082 is->iformat = iformat;
3086 /* start video display */
3087 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3089 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3091 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3094 if (packet_queue_init(&is->videoq) < 0 ||
3095 packet_queue_init(&is->audioq) < 0 ||
3096 packet_queue_init(&is->subtitleq) < 0)
3099 if (!(is->continue_read_thread = SDL_CreateCond())) {
3100 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3104 init_clock(&is->vidclk, &is->videoq.serial);
3105 init_clock(&is->audclk, &is->audioq.serial);
3106 init_clock(&is->extclk, &is->extclk.serial);
3107 is->audio_clock_serial = -1;
3108 is->audio_volume = SDL_MIX_MAXVOLUME;
3110 is->av_sync_type = av_sync_type;
3111 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3112 if (!is->read_tid) {
3113 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3121 static void stream_cycle_channel(VideoState *is, int codec_type)
3123 AVFormatContext *ic = is->ic;
3124 int start_index, stream_index;
3127 AVProgram *p = NULL;
3128 int nb_streams = is->ic->nb_streams;
3130 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3131 start_index = is->last_video_stream;
3132 old_index = is->video_stream;
3133 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3134 start_index = is->last_audio_stream;
3135 old_index = is->audio_stream;
3137 start_index = is->last_subtitle_stream;
3138 old_index = is->subtitle_stream;
3140 stream_index = start_index;
3142 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3143 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3145 nb_streams = p->nb_stream_indexes;
3146 for (start_index = 0; start_index < nb_streams; start_index++)
3147 if (p->stream_index[start_index] == stream_index)
3149 if (start_index == nb_streams)
3151 stream_index = start_index;
3156 if (++stream_index >= nb_streams)
3158 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3161 is->last_subtitle_stream = -1;
3164 if (start_index == -1)
3168 if (stream_index == start_index)
3170 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3171 if (st->codecpar->codec_type == codec_type) {
3172 /* check that parameters are OK */
3173 switch (codec_type) {
3174 case AVMEDIA_TYPE_AUDIO:
3175 if (st->codecpar->sample_rate != 0 &&
3176 st->codecpar->channels != 0)
3179 case AVMEDIA_TYPE_VIDEO:
3180 case AVMEDIA_TYPE_SUBTITLE:
3188 if (p && stream_index != -1)
3189 stream_index = p->stream_index[stream_index];
3190 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3191 av_get_media_type_string(codec_type),
3195 stream_component_close(is, old_index);
3196 stream_component_open(is, stream_index);
3200 static void toggle_full_screen(VideoState *is)
3202 is_full_screen = !is_full_screen;
3203 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3206 static void toggle_audio_display(VideoState *is)
3208 int next = is->show_mode;
3210 next = (next + 1) % SHOW_MODE_NB;
3211 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3212 if (is->show_mode != next) {
3213 is->force_refresh = 1;
3214 is->show_mode = next;
3218 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3219 double remaining_time = 0.0;
3221 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3222 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3226 if (remaining_time > 0.0)
3227 av_usleep((int64_t)(remaining_time * 1000000.0));
3228 remaining_time = REFRESH_RATE;
3229 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3230 video_refresh(is, &remaining_time);
3235 static void seek_chapter(VideoState *is, int incr)
3237 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3240 if (!is->ic->nb_chapters)
3243 /* find the current chapter */
3244 for (i = 0; i < is->ic->nb_chapters; i++) {
3245 AVChapter *ch = is->ic->chapters[i];
3246 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3254 if (i >= is->ic->nb_chapters)
3257 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3258 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3259 AV_TIME_BASE_Q), 0, 0);
3262 /* handle an event sent by the GUI */
3263 static void event_loop(VideoState *cur_stream)
3266 double incr, pos, frac;
3270 refresh_loop_wait_event(cur_stream, &event);
3271 switch (event.type) {
3273 if (exit_on_keydown) {
3274 do_exit(cur_stream);
3277 switch (event.key.keysym.sym) {
3280 do_exit(cur_stream);
3283 toggle_full_screen(cur_stream);
3284 cur_stream->force_refresh = 1;
3288 toggle_pause(cur_stream);
3291 toggle_mute(cur_stream);
3293 case SDLK_KP_MULTIPLY:
3295 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3297 case SDLK_KP_DIVIDE:
3299 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3301 case SDLK_s: // S: Step to next frame
3302 step_to_next_frame(cur_stream);
3305 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3308 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3311 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3312 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3313 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3316 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3320 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3321 if (++cur_stream->vfilter_idx >= nb_vfilters)
3322 cur_stream->vfilter_idx = 0;
3324 cur_stream->vfilter_idx = 0;
3325 toggle_audio_display(cur_stream);
3328 toggle_audio_display(cur_stream);
3332 if (cur_stream->ic->nb_chapters <= 1) {
3336 seek_chapter(cur_stream, 1);
3339 if (cur_stream->ic->nb_chapters <= 1) {
3343 seek_chapter(cur_stream, -1);
3357 if (seek_by_bytes) {
3359 if (pos < 0 && cur_stream->video_stream >= 0)
3360 pos = frame_queue_last_pos(&cur_stream->pictq);
3361 if (pos < 0 && cur_stream->audio_stream >= 0)
3362 pos = frame_queue_last_pos(&cur_stream->sampq);
3364 pos = avio_tell(cur_stream->ic->pb);
3365 if (cur_stream->ic->bit_rate)
3366 incr *= cur_stream->ic->bit_rate / 8.0;
3370 stream_seek(cur_stream, pos, incr, 1);
3372 pos = get_master_clock(cur_stream);
3374 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3376 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3377 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3378 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3385 case SDL_MOUSEBUTTONDOWN:
3386 if (exit_on_mousedown) {
3387 do_exit(cur_stream);
3390 if (event.button.button == SDL_BUTTON_LEFT) {
3391 static int64_t last_mouse_left_click = 0;
3392 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3393 toggle_full_screen(cur_stream);
3394 cur_stream->force_refresh = 1;
3395 last_mouse_left_click = 0;
3397 last_mouse_left_click = av_gettime_relative();
3400 case SDL_MOUSEMOTION:
3401 if (cursor_hidden) {
3405 cursor_last_shown = av_gettime_relative();
3406 if (event.type == SDL_MOUSEBUTTONDOWN) {
3407 if (event.button.button != SDL_BUTTON_RIGHT)
3411 if (!(event.motion.state & SDL_BUTTON_RMASK))
3415 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3416 uint64_t size = avio_size(cur_stream->ic->pb);
3417 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3421 int tns, thh, tmm, tss;
3422 tns = cur_stream->ic->duration / 1000000LL;
3424 tmm = (tns % 3600) / 60;
3426 frac = x / cur_stream->width;
3429 mm = (ns % 3600) / 60;
3431 av_log(NULL, AV_LOG_INFO,
3432 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3433 hh, mm, ss, thh, tmm, tss);
3434 ts = frac * cur_stream->ic->duration;
3435 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3436 ts += cur_stream->ic->start_time;
3437 stream_seek(cur_stream, ts, 0, 0);
3440 case SDL_WINDOWEVENT:
3441 switch (event.window.event) {
3442 case SDL_WINDOWEVENT_RESIZED:
3443 screen_width = cur_stream->width = event.window.data1;
3444 screen_height = cur_stream->height = event.window.data2;
3445 if (cur_stream->vis_texture) {
3446 SDL_DestroyTexture(cur_stream->vis_texture);
3447 cur_stream->vis_texture = NULL;
3449 case SDL_WINDOWEVENT_EXPOSED:
3450 cur_stream->force_refresh = 1;
3455 do_exit(cur_stream);
3457 case FF_ALLOC_EVENT:
3458 alloc_picture(event.user.data1);
3466 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3468 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3469 return opt_default(NULL, "video_size", arg);
3472 static int opt_width(void *optctx, const char *opt, const char *arg)
3474 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3478 static int opt_height(void *optctx, const char *opt, const char *arg)
3480 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3484 static int opt_format(void *optctx, const char *opt, const char *arg)
3486 file_iformat = av_find_input_format(arg);
3487 if (!file_iformat) {
3488 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3489 return AVERROR(EINVAL);
3494 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3496 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3497 return opt_default(NULL, "pixel_format", arg);
3500 static int opt_sync(void *optctx, const char *opt, const char *arg)
3502 if (!strcmp(arg, "audio"))
3503 av_sync_type = AV_SYNC_AUDIO_MASTER;
3504 else if (!strcmp(arg, "video"))
3505 av_sync_type = AV_SYNC_VIDEO_MASTER;
3506 else if (!strcmp(arg, "ext"))
3507 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3509 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3515 static int opt_seek(void *optctx, const char *opt, const char *arg)
3517 start_time = parse_time_or_die(opt, arg, 1);
3521 static int opt_duration(void *optctx, const char *opt, const char *arg)
3523 duration = parse_time_or_die(opt, arg, 1);
3527 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3529 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3530 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3531 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3532 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3536 static void opt_input_file(void *optctx, const char *filename)
3538 if (input_filename) {
3539 av_log(NULL, AV_LOG_FATAL,
3540 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3541 filename, input_filename);
3544 if (!strcmp(filename, "-"))
3546 input_filename = filename;
3549 static int opt_codec(void *optctx, const char *opt, const char *arg)
3551 const char *spec = strchr(opt, ':');
3553 av_log(NULL, AV_LOG_ERROR,
3554 "No media specifier was specified in '%s' in option '%s'\n",
3556 return AVERROR(EINVAL);
3560 case 'a' : audio_codec_name = arg; break;
3561 case 's' : subtitle_codec_name = arg; break;
3562 case 'v' : video_codec_name = arg; break;
3564 av_log(NULL, AV_LOG_ERROR,
3565 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3566 return AVERROR(EINVAL);
3573 static const OptionDef options[] = {
3574 #include "cmdutils_common_opts.h"
3575 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3576 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3577 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3578 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3579 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3580 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3581 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3582 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3583 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3584 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3585 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3586 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3587 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3588 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3589 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3590 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3591 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3592 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3593 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3594 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3595 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3596 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3597 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3598 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3599 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3600 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3601 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3602 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3603 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3605 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3606 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3608 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3609 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3610 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3611 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3612 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3613 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3614 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3615 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3616 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3620 static void show_usage(void)
3622 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3623 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3624 av_log(NULL, AV_LOG_INFO, "\n");
3627 void show_help_default(const char *opt, const char *arg)
3629 av_log_set_callback(log_callback_help);
3631 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3632 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3634 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3635 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3636 #if !CONFIG_AVFILTER
3637 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3639 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3641 printf("\nWhile playing:\n"
3643 "f toggle full screen\n"
3646 "9, 0 decrease and increase volume respectively\n"
3647 "/, * decrease and increase volume respectively\n"
3648 "a cycle audio channel in the current program\n"
3649 "v cycle video channel\n"
3650 "t cycle subtitle channel in the current program\n"
3652 "w cycle video filters or show modes\n"
3653 "s activate frame-step mode\n"
3654 "left/right seek backward/forward 10 seconds\n"
3655 "down/up seek backward/forward 1 minute\n"
3656 "page down/page up seek backward/forward 10 minutes\n"
3657 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3658 "left double-click toggle full screen\n"
3662 static int lockmgr(void **mtx, enum AVLockOp op)
3665 case AV_LOCK_CREATE:
3666 *mtx = SDL_CreateMutex();
3668 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3672 case AV_LOCK_OBTAIN:
3673 return !!SDL_LockMutex(*mtx);
3674 case AV_LOCK_RELEASE:
3675 return !!SDL_UnlockMutex(*mtx);
3676 case AV_LOCK_DESTROY:
3677 SDL_DestroyMutex(*mtx);
3683 /* Called from the main */
3684 int main(int argc, char **argv)
3691 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3692 parse_loglevel(argc, argv, options);
3694 /* register all codecs, demux and protocols */
3696 avdevice_register_all();
3699 avfilter_register_all();
3702 avformat_network_init();
3706 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3707 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3709 show_banner(argc, argv, options);
3711 parse_options(NULL, argc, argv, options, opt_input_file);
3713 if (!input_filename) {
3715 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3716 av_log(NULL, AV_LOG_FATAL,
3717 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3721 if (display_disable) {
3724 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3726 flags &= ~SDL_INIT_AUDIO;
3728 /* Try to work around an occasional ALSA buffer underflow issue when the
3729 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3730 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3731 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3733 if (display_disable)
3734 flags &= ~SDL_INIT_VIDEO;
3735 if (SDL_Init (flags)) {
3736 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3737 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3741 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3742 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3744 if (av_lockmgr_register(lockmgr)) {
3745 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3749 av_init_packet(&flush_pkt);
3750 flush_pkt.data = (uint8_t *)&flush_pkt;
3752 is = stream_open(input_filename, file_iformat);
3754 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");