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 */
169 typedef struct FrameQueue {
170 Frame queue[FRAME_QUEUE_SIZE];
183 AV_SYNC_AUDIO_MASTER, /* default choice */
184 AV_SYNC_VIDEO_MASTER,
185 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
188 typedef struct Decoder {
192 AVCodecContext *avctx;
196 SDL_cond *empty_queue_cond;
198 AVRational start_pts_tb;
200 AVRational next_pts_tb;
201 SDL_Thread *decoder_tid;
204 typedef struct VideoState {
205 SDL_Thread *read_tid;
206 AVInputFormat *iformat;
211 int queue_attachments_req;
216 int read_pause_return;
237 int audio_clock_serial;
238 double audio_diff_cum; /* used for AV difference average computation */
239 double audio_diff_avg_coef;
240 double audio_diff_threshold;
241 int audio_diff_avg_count;
244 int audio_hw_buf_size;
247 unsigned int audio_buf_size; /* in bytes */
248 unsigned int audio_buf1_size;
249 int audio_buf_index; /* in bytes */
250 int audio_write_buf_size;
253 struct AudioParams audio_src;
255 struct AudioParams audio_filter_src;
257 struct AudioParams audio_tgt;
258 struct SwrContext *swr_ctx;
259 int frame_drops_early;
260 int frame_drops_late;
263 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
265 int16_t sample_array[SAMPLE_ARRAY_SIZE];
266 int sample_array_index;
270 FFTSample *rdft_data;
272 double last_vis_time;
273 SDL_Texture *vis_texture;
274 SDL_Texture *sub_texture;
275 SDL_Texture *vid_texture;
278 AVStream *subtitle_st;
279 PacketQueue subtitleq;
282 double frame_last_returned_time;
283 double frame_last_filter_delay;
287 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
288 struct SwsContext *img_convert_ctx;
289 struct SwsContext *sub_convert_ctx;
293 int width, height, xleft, ytop;
298 AVFilterContext *in_video_filter; // the first filter in the video chain
299 AVFilterContext *out_video_filter; // the last filter in the video chain
300 AVFilterContext *in_audio_filter; // the first filter in the audio chain
301 AVFilterContext *out_audio_filter; // the last filter in the audio chain
302 AVFilterGraph *agraph; // audio filter graph
305 int last_video_stream, last_audio_stream, last_subtitle_stream;
307 SDL_cond *continue_read_thread;
310 /* options specified by the user */
311 static AVInputFormat *file_iformat;
312 static const char *input_filename;
313 static const char *window_title;
314 static int default_width = 640;
315 static int default_height = 480;
316 static int screen_width = 0;
317 static int screen_height = 0;
318 static int audio_disable;
319 static int video_disable;
320 static int subtitle_disable;
321 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
322 static int seek_by_bytes = -1;
323 static int display_disable;
324 static int borderless;
325 static int startup_volume = 100;
326 static int show_status = 1;
327 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
328 static int64_t start_time = AV_NOPTS_VALUE;
329 static int64_t duration = AV_NOPTS_VALUE;
331 static int genpts = 0;
332 static int lowres = 0;
333 static int decoder_reorder_pts = -1;
335 static int exit_on_keydown;
336 static int exit_on_mousedown;
338 static int framedrop = -1;
339 static int infinite_buffer = -1;
340 static enum ShowMode show_mode = SHOW_MODE_NONE;
341 static const char *audio_codec_name;
342 static const char *subtitle_codec_name;
343 static const char *video_codec_name;
344 double rdftspeed = 0.02;
345 static int64_t cursor_last_shown;
346 static int cursor_hidden = 0;
348 static const char **vfilters_list = NULL;
349 static int nb_vfilters = 0;
350 static char *afilters = NULL;
352 static int autorotate = 1;
354 /* current context */
355 static int is_full_screen;
356 static int64_t audio_callback_time;
358 static AVPacket flush_pkt;
360 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
362 static SDL_Window *window;
363 static SDL_Renderer *renderer;
366 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
368 GROW_ARRAY(vfilters_list, nb_vfilters);
369 vfilters_list[nb_vfilters - 1] = arg;
375 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
376 enum AVSampleFormat fmt2, int64_t channel_count2)
378 /* If channel count == 1, planar and non-planar formats are the same */
379 if (channel_count1 == 1 && channel_count2 == 1)
380 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
382 return channel_count1 != channel_count2 || fmt1 != fmt2;
386 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
388 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
389 return channel_layout;
394 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
396 MyAVPacketList *pkt1;
398 if (q->abort_request)
401 pkt1 = av_malloc(sizeof(MyAVPacketList));
406 if (pkt == &flush_pkt)
408 pkt1->serial = q->serial;
413 q->last_pkt->next = pkt1;
416 q->size += pkt1->pkt.size + sizeof(*pkt1);
417 q->duration += pkt1->pkt.duration;
418 /* XXX: should duplicate packet data in DV case */
419 SDL_CondSignal(q->cond);
423 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
427 SDL_LockMutex(q->mutex);
428 ret = packet_queue_put_private(q, pkt);
429 SDL_UnlockMutex(q->mutex);
431 if (pkt != &flush_pkt && ret < 0)
432 av_packet_unref(pkt);
437 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
439 AVPacket pkt1, *pkt = &pkt1;
443 pkt->stream_index = stream_index;
444 return packet_queue_put(q, pkt);
447 /* packet queue handling */
448 static int packet_queue_init(PacketQueue *q)
450 memset(q, 0, sizeof(PacketQueue));
451 q->mutex = SDL_CreateMutex();
453 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
454 return AVERROR(ENOMEM);
456 q->cond = SDL_CreateCond();
458 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
459 return AVERROR(ENOMEM);
461 q->abort_request = 1;
465 static void packet_queue_flush(PacketQueue *q)
467 MyAVPacketList *pkt, *pkt1;
469 SDL_LockMutex(q->mutex);
470 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
472 av_packet_unref(&pkt->pkt);
480 SDL_UnlockMutex(q->mutex);
483 static void packet_queue_destroy(PacketQueue *q)
485 packet_queue_flush(q);
486 SDL_DestroyMutex(q->mutex);
487 SDL_DestroyCond(q->cond);
490 static void packet_queue_abort(PacketQueue *q)
492 SDL_LockMutex(q->mutex);
494 q->abort_request = 1;
496 SDL_CondSignal(q->cond);
498 SDL_UnlockMutex(q->mutex);
501 static void packet_queue_start(PacketQueue *q)
503 SDL_LockMutex(q->mutex);
504 q->abort_request = 0;
505 packet_queue_put_private(q, &flush_pkt);
506 SDL_UnlockMutex(q->mutex);
509 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
510 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
512 MyAVPacketList *pkt1;
515 SDL_LockMutex(q->mutex);
518 if (q->abort_request) {
525 q->first_pkt = pkt1->next;
529 q->size -= pkt1->pkt.size + sizeof(*pkt1);
530 q->duration -= pkt1->pkt.duration;
533 *serial = pkt1->serial;
541 SDL_CondWait(q->cond, q->mutex);
544 SDL_UnlockMutex(q->mutex);
548 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
549 memset(d, 0, sizeof(Decoder));
552 d->empty_queue_cond = empty_queue_cond;
553 d->start_pts = AV_NOPTS_VALUE;
556 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
562 if (d->queue->abort_request)
565 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
568 if (d->queue->nb_packets == 0)
569 SDL_CondSignal(d->empty_queue_cond);
570 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
572 if (pkt.data == flush_pkt.data) {
573 avcodec_flush_buffers(d->avctx);
575 d->next_pts = d->start_pts;
576 d->next_pts_tb = d->start_pts_tb;
578 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
579 av_packet_unref(&d->pkt);
580 d->pkt_temp = d->pkt = pkt;
581 d->packet_pending = 1;
584 switch (d->avctx->codec_type) {
585 case AVMEDIA_TYPE_VIDEO:
586 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
588 if (decoder_reorder_pts == -1) {
589 frame->pts = av_frame_get_best_effort_timestamp(frame);
590 } else if (!decoder_reorder_pts) {
591 frame->pts = frame->pkt_dts;
595 case AVMEDIA_TYPE_AUDIO:
596 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
598 AVRational tb = (AVRational){1, frame->sample_rate};
599 if (frame->pts != AV_NOPTS_VALUE)
600 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
601 else if (d->next_pts != AV_NOPTS_VALUE)
602 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
603 if (frame->pts != AV_NOPTS_VALUE) {
604 d->next_pts = frame->pts + frame->nb_samples;
609 case AVMEDIA_TYPE_SUBTITLE:
610 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
615 d->packet_pending = 0;
618 d->pkt_temp.pts = AV_NOPTS_VALUE;
619 if (d->pkt_temp.data) {
620 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
621 ret = d->pkt_temp.size;
622 d->pkt_temp.data += ret;
623 d->pkt_temp.size -= ret;
624 if (d->pkt_temp.size <= 0)
625 d->packet_pending = 0;
628 d->packet_pending = 0;
629 d->finished = d->pkt_serial;
633 } while (!got_frame && !d->finished);
638 static void decoder_destroy(Decoder *d) {
639 av_packet_unref(&d->pkt);
640 avcodec_free_context(&d->avctx);
643 static void frame_queue_unref_item(Frame *vp)
645 av_frame_unref(vp->frame);
646 avsubtitle_free(&vp->sub);
649 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
652 memset(f, 0, sizeof(FrameQueue));
653 if (!(f->mutex = SDL_CreateMutex())) {
654 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
655 return AVERROR(ENOMEM);
657 if (!(f->cond = SDL_CreateCond())) {
658 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
659 return AVERROR(ENOMEM);
662 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
663 f->keep_last = !!keep_last;
664 for (i = 0; i < f->max_size; i++)
665 if (!(f->queue[i].frame = av_frame_alloc()))
666 return AVERROR(ENOMEM);
670 static void frame_queue_destory(FrameQueue *f)
673 for (i = 0; i < f->max_size; i++) {
674 Frame *vp = &f->queue[i];
675 frame_queue_unref_item(vp);
676 av_frame_free(&vp->frame);
678 SDL_DestroyMutex(f->mutex);
679 SDL_DestroyCond(f->cond);
682 static void frame_queue_signal(FrameQueue *f)
684 SDL_LockMutex(f->mutex);
685 SDL_CondSignal(f->cond);
686 SDL_UnlockMutex(f->mutex);
689 static Frame *frame_queue_peek(FrameQueue *f)
691 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
694 static Frame *frame_queue_peek_next(FrameQueue *f)
696 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
699 static Frame *frame_queue_peek_last(FrameQueue *f)
701 return &f->queue[f->rindex];
704 static Frame *frame_queue_peek_writable(FrameQueue *f)
706 /* wait until we have space to put a new frame */
707 SDL_LockMutex(f->mutex);
708 while (f->size >= f->max_size &&
709 !f->pktq->abort_request) {
710 SDL_CondWait(f->cond, f->mutex);
712 SDL_UnlockMutex(f->mutex);
714 if (f->pktq->abort_request)
717 return &f->queue[f->windex];
720 static Frame *frame_queue_peek_readable(FrameQueue *f)
722 /* wait until we have a readable a new frame */
723 SDL_LockMutex(f->mutex);
724 while (f->size - f->rindex_shown <= 0 &&
725 !f->pktq->abort_request) {
726 SDL_CondWait(f->cond, f->mutex);
728 SDL_UnlockMutex(f->mutex);
730 if (f->pktq->abort_request)
733 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
736 static void frame_queue_push(FrameQueue *f)
738 if (++f->windex == f->max_size)
740 SDL_LockMutex(f->mutex);
742 SDL_CondSignal(f->cond);
743 SDL_UnlockMutex(f->mutex);
746 static void frame_queue_next(FrameQueue *f)
748 if (f->keep_last && !f->rindex_shown) {
752 frame_queue_unref_item(&f->queue[f->rindex]);
753 if (++f->rindex == f->max_size)
755 SDL_LockMutex(f->mutex);
757 SDL_CondSignal(f->cond);
758 SDL_UnlockMutex(f->mutex);
761 /* return the number of undisplayed frames in the queue */
762 static int frame_queue_nb_remaining(FrameQueue *f)
764 return f->size - f->rindex_shown;
767 /* return last shown position */
768 static int64_t frame_queue_last_pos(FrameQueue *f)
770 Frame *fp = &f->queue[f->rindex];
771 if (f->rindex_shown && fp->serial == f->pktq->serial)
777 static void decoder_abort(Decoder *d, FrameQueue *fq)
779 packet_queue_abort(d->queue);
780 frame_queue_signal(fq);
781 SDL_WaitThread(d->decoder_tid, NULL);
782 d->decoder_tid = NULL;
783 packet_queue_flush(d->queue);
786 static inline void fill_rectangle(int x, int y, int w, int h)
794 SDL_RenderFillRect(renderer, &rect);
797 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
801 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
804 SDL_DestroyTexture(*texture);
805 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
807 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
810 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
812 memset(pixels, 0, pitch * new_height);
813 SDL_UnlockTexture(*texture);
819 static void calculate_display_rect(SDL_Rect *rect,
820 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
821 int pic_width, int pic_height, AVRational pic_sar)
824 int width, height, x, y;
826 if (pic_sar.num == 0)
829 aspect_ratio = av_q2d(pic_sar);
831 if (aspect_ratio <= 0.0)
833 aspect_ratio *= (float)pic_width / (float)pic_height;
835 /* XXX: we suppose the screen has a 1.0 pixel ratio */
837 width = lrint(height * aspect_ratio) & ~1;
838 if (width > scr_width) {
840 height = lrint(width / aspect_ratio) & ~1;
842 x = (scr_width - width) / 2;
843 y = (scr_height - height) / 2;
844 rect->x = scr_xleft + x;
845 rect->y = scr_ytop + y;
846 rect->w = FFMAX(width, 1);
847 rect->h = FFMAX(height, 1);
850 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
852 switch (frame->format) {
853 case AV_PIX_FMT_YUV420P:
854 if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
855 av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
858 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
859 frame->data[1], frame->linesize[1],
860 frame->data[2], frame->linesize[2]);
862 case AV_PIX_FMT_BGRA:
863 if (frame->linesize[0] < 0) {
864 ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
866 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
870 /* This should only happen if we are not using avfilter... */
871 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
872 frame->width, frame->height, frame->format, frame->width, frame->height,
873 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
874 if (*img_convert_ctx != NULL) {
877 if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) {
878 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
879 0, frame->height, pixels, pitch);
880 SDL_UnlockTexture(tex);
883 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
891 static void video_image_display(VideoState *is)
897 vp = frame_queue_peek_last(&is->pictq);
898 if (is->subtitle_st) {
899 if (frame_queue_nb_remaining(&is->subpq) > 0) {
900 sp = frame_queue_peek(&is->subpq);
902 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
907 if (!sp->width || !sp->height) {
908 sp->width = vp->width;
909 sp->height = vp->height;
911 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
914 for (i = 0; i < sp->sub.num_rects; i++) {
915 AVSubtitleRect *sub_rect = sp->sub.rects[i];
917 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
918 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
919 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
920 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
922 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
923 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
924 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
925 0, NULL, NULL, NULL);
926 if (!is->sub_convert_ctx) {
927 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
930 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
931 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
932 0, sub_rect->h, pixels, pitch);
933 SDL_UnlockTexture(is->sub_texture);
943 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
946 int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888;
947 if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0)
949 if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
952 vp->flip_v = vp->frame->linesize[0] < 0;
955 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
957 #if USE_ONEPASS_SUBTITLE_RENDER
958 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
961 double xratio = (double)rect.w / (double)sp->width;
962 double yratio = (double)rect.h / (double)sp->height;
963 for (i = 0; i < sp->sub.num_rects; i++) {
964 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
965 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
966 .y = rect.y + sub_rect->y * yratio,
967 .w = sub_rect->w * xratio,
968 .h = sub_rect->h * yratio};
969 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
975 static inline int compute_mod(int a, int b)
977 return a < 0 ? a%b + b : a%b;
980 static void video_audio_display(VideoState *s)
982 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
983 int ch, channels, h, h2;
985 int rdft_bits, nb_freq;
987 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
989 nb_freq = 1 << (rdft_bits - 1);
991 /* compute display index : center on currently output samples */
992 channels = s->audio_tgt.channels;
993 nb_display_channels = channels;
995 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
997 delay = s->audio_write_buf_size;
1000 /* to be more precise, we take into account the time spent since
1001 the last buffer computation */
1002 if (audio_callback_time) {
1003 time_diff = av_gettime_relative() - audio_callback_time;
1004 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1007 delay += 2 * data_used;
1008 if (delay < data_used)
1011 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1012 if (s->show_mode == SHOW_MODE_WAVES) {
1014 for (i = 0; i < 1000; i += channels) {
1015 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1016 int a = s->sample_array[idx];
1017 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1018 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1019 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1021 if (h < score && (b ^ c) < 0) {
1028 s->last_i_start = i_start;
1030 i_start = s->last_i_start;
1033 if (s->show_mode == SHOW_MODE_WAVES) {
1034 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1036 /* total height for one channel */
1037 h = s->height / nb_display_channels;
1038 /* graph height / 2 */
1040 for (ch = 0; ch < nb_display_channels; ch++) {
1042 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1043 for (x = 0; x < s->width; x++) {
1044 y = (s->sample_array[i] * h2) >> 15;
1051 fill_rectangle(s->xleft + x, ys, 1, y);
1053 if (i >= SAMPLE_ARRAY_SIZE)
1054 i -= SAMPLE_ARRAY_SIZE;
1058 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1060 for (ch = 1; ch < nb_display_channels; ch++) {
1061 y = s->ytop + ch * h;
1062 fill_rectangle(s->xleft, y, s->width, 1);
1065 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1068 nb_display_channels= FFMIN(nb_display_channels, 2);
1069 if (rdft_bits != s->rdft_bits) {
1070 av_rdft_end(s->rdft);
1071 av_free(s->rdft_data);
1072 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1073 s->rdft_bits = rdft_bits;
1074 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1076 if (!s->rdft || !s->rdft_data){
1077 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1078 s->show_mode = SHOW_MODE_WAVES;
1081 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1084 for (ch = 0; ch < nb_display_channels; ch++) {
1085 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1087 for (x = 0; x < 2 * nb_freq; x++) {
1088 double w = (x-nb_freq) * (1.0 / nb_freq);
1089 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1091 if (i >= SAMPLE_ARRAY_SIZE)
1092 i -= SAMPLE_ARRAY_SIZE;
1094 av_rdft_calc(s->rdft, data[ch]);
1096 /* Least efficient way to do this, we should of course
1097 * directly access it but it is more than fast enough. */
1098 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1100 pixels += pitch * s->height;
1101 for (y = 0; y < s->height; y++) {
1102 double w = 1 / sqrt(nb_freq);
1103 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]));
1104 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1109 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1111 SDL_UnlockTexture(s->vis_texture);
1113 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1117 if (s->xpos >= s->width)
1122 static void stream_component_close(VideoState *is, int stream_index)
1124 AVFormatContext *ic = is->ic;
1125 AVCodecParameters *codecpar;
1127 if (stream_index < 0 || stream_index >= ic->nb_streams)
1129 codecpar = ic->streams[stream_index]->codecpar;
1131 switch (codecpar->codec_type) {
1132 case AVMEDIA_TYPE_AUDIO:
1133 decoder_abort(&is->auddec, &is->sampq);
1135 decoder_destroy(&is->auddec);
1136 swr_free(&is->swr_ctx);
1137 av_freep(&is->audio_buf1);
1138 is->audio_buf1_size = 0;
1139 is->audio_buf = NULL;
1142 av_rdft_end(is->rdft);
1143 av_freep(&is->rdft_data);
1148 case AVMEDIA_TYPE_VIDEO:
1149 decoder_abort(&is->viddec, &is->pictq);
1150 decoder_destroy(&is->viddec);
1152 case AVMEDIA_TYPE_SUBTITLE:
1153 decoder_abort(&is->subdec, &is->subpq);
1154 decoder_destroy(&is->subdec);
1160 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1161 switch (codecpar->codec_type) {
1162 case AVMEDIA_TYPE_AUDIO:
1163 is->audio_st = NULL;
1164 is->audio_stream = -1;
1166 case AVMEDIA_TYPE_VIDEO:
1167 is->video_st = NULL;
1168 is->video_stream = -1;
1170 case AVMEDIA_TYPE_SUBTITLE:
1171 is->subtitle_st = NULL;
1172 is->subtitle_stream = -1;
1179 static void stream_close(VideoState *is)
1181 /* XXX: use a special url_shutdown call to abort parse cleanly */
1182 is->abort_request = 1;
1183 SDL_WaitThread(is->read_tid, NULL);
1185 /* close each stream */
1186 if (is->audio_stream >= 0)
1187 stream_component_close(is, is->audio_stream);
1188 if (is->video_stream >= 0)
1189 stream_component_close(is, is->video_stream);
1190 if (is->subtitle_stream >= 0)
1191 stream_component_close(is, is->subtitle_stream);
1193 avformat_close_input(&is->ic);
1195 packet_queue_destroy(&is->videoq);
1196 packet_queue_destroy(&is->audioq);
1197 packet_queue_destroy(&is->subtitleq);
1199 /* free all pictures */
1200 frame_queue_destory(&is->pictq);
1201 frame_queue_destory(&is->sampq);
1202 frame_queue_destory(&is->subpq);
1203 SDL_DestroyCond(is->continue_read_thread);
1204 sws_freeContext(is->img_convert_ctx);
1205 sws_freeContext(is->sub_convert_ctx);
1206 av_free(is->filename);
1207 if (is->vis_texture)
1208 SDL_DestroyTexture(is->vis_texture);
1209 if (is->vid_texture)
1210 SDL_DestroyTexture(is->vid_texture);
1211 if (is->sub_texture)
1212 SDL_DestroyTexture(is->sub_texture);
1216 static void do_exit(VideoState *is)
1222 SDL_DestroyRenderer(renderer);
1224 SDL_DestroyWindow(window);
1225 av_lockmgr_register(NULL);
1228 av_freep(&vfilters_list);
1230 avformat_network_deinit();
1234 av_log(NULL, AV_LOG_QUIET, "%s", "");
1238 static void sigterm_handler(int sig)
1243 static void set_default_window_size(int width, int height, AVRational sar)
1246 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1247 default_width = rect.w;
1248 default_height = rect.h;
1251 static int video_open(VideoState *is)
1264 int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
1266 window_title = input_filename;
1268 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1270 flags |= SDL_WINDOW_BORDERLESS;
1271 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1272 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1274 SDL_RendererInfo info;
1275 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1277 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1278 renderer = SDL_CreateRenderer(window, -1, 0);
1281 if (!SDL_GetRendererInfo(renderer, &info))
1282 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1286 SDL_SetWindowSize(window, w, h);
1289 if (!window || !renderer) {
1290 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1300 /* display the current picture, if any */
1301 static void video_display(VideoState *is)
1306 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1307 SDL_RenderClear(renderer);
1308 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1309 video_audio_display(is);
1310 else if (is->video_st)
1311 video_image_display(is);
1312 SDL_RenderPresent(renderer);
1315 static double get_clock(Clock *c)
1317 if (*c->queue_serial != c->serial)
1322 double time = av_gettime_relative() / 1000000.0;
1323 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1327 static void set_clock_at(Clock *c, double pts, int serial, double time)
1330 c->last_updated = time;
1331 c->pts_drift = c->pts - time;
1335 static void set_clock(Clock *c, double pts, int serial)
1337 double time = av_gettime_relative() / 1000000.0;
1338 set_clock_at(c, pts, serial, time);
1341 static void set_clock_speed(Clock *c, double speed)
1343 set_clock(c, get_clock(c), c->serial);
1347 static void init_clock(Clock *c, int *queue_serial)
1351 c->queue_serial = queue_serial;
1352 set_clock(c, NAN, -1);
1355 static void sync_clock_to_slave(Clock *c, Clock *slave)
1357 double clock = get_clock(c);
1358 double slave_clock = get_clock(slave);
1359 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1360 set_clock(c, slave_clock, slave->serial);
1363 static int get_master_sync_type(VideoState *is) {
1364 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1366 return AV_SYNC_VIDEO_MASTER;
1368 return AV_SYNC_AUDIO_MASTER;
1369 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1371 return AV_SYNC_AUDIO_MASTER;
1373 return AV_SYNC_EXTERNAL_CLOCK;
1375 return AV_SYNC_EXTERNAL_CLOCK;
1379 /* get the current master clock value */
1380 static double get_master_clock(VideoState *is)
1384 switch (get_master_sync_type(is)) {
1385 case AV_SYNC_VIDEO_MASTER:
1386 val = get_clock(&is->vidclk);
1388 case AV_SYNC_AUDIO_MASTER:
1389 val = get_clock(&is->audclk);
1392 val = get_clock(&is->extclk);
1398 static void check_external_clock_speed(VideoState *is) {
1399 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1400 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1401 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1402 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1403 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1404 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1406 double speed = is->extclk.speed;
1408 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1412 /* seek in the stream */
1413 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1415 if (!is->seek_req) {
1418 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1420 is->seek_flags |= AVSEEK_FLAG_BYTE;
1422 SDL_CondSignal(is->continue_read_thread);
1426 /* pause or resume the video */
1427 static void stream_toggle_pause(VideoState *is)
1430 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1431 if (is->read_pause_return != AVERROR(ENOSYS)) {
1432 is->vidclk.paused = 0;
1434 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1436 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1437 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1440 static void toggle_pause(VideoState *is)
1442 stream_toggle_pause(is);
1446 static void toggle_mute(VideoState *is)
1448 is->muted = !is->muted;
1451 static void update_volume(VideoState *is, int sign, int step)
1453 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1456 static void step_to_next_frame(VideoState *is)
1458 /* if the stream is paused unpause it, then step */
1460 stream_toggle_pause(is);
1464 static double compute_target_delay(double delay, VideoState *is)
1466 double sync_threshold, diff = 0;
1468 /* update delay to follow master synchronisation source */
1469 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1470 /* if video is slave, we try to correct big delays by
1471 duplicating or deleting a frame */
1472 diff = get_clock(&is->vidclk) - get_master_clock(is);
1474 /* skip or repeat frame. We take into account the
1475 delay to compute the threshold. I still don't know
1476 if it is the best guess */
1477 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1478 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1479 if (diff <= -sync_threshold)
1480 delay = FFMAX(0, delay + diff);
1481 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1482 delay = delay + diff;
1483 else if (diff >= sync_threshold)
1488 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1494 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1495 if (vp->serial == nextvp->serial) {
1496 double duration = nextvp->pts - vp->pts;
1497 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1498 return vp->duration;
1506 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1507 /* update current video pts */
1508 set_clock(&is->vidclk, pts, serial);
1509 sync_clock_to_slave(&is->extclk, &is->vidclk);
1512 /* called to display each frame */
1513 static void video_refresh(void *opaque, double *remaining_time)
1515 VideoState *is = opaque;
1520 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1521 check_external_clock_speed(is);
1523 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1524 time = av_gettime_relative() / 1000000.0;
1525 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1527 is->last_vis_time = time;
1529 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1534 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1535 // nothing to do, no picture to display in the queue
1537 double last_duration, duration, delay;
1540 /* dequeue the picture */
1541 lastvp = frame_queue_peek_last(&is->pictq);
1542 vp = frame_queue_peek(&is->pictq);
1544 if (vp->serial != is->videoq.serial) {
1545 frame_queue_next(&is->pictq);
1549 if (lastvp->serial != vp->serial)
1550 is->frame_timer = av_gettime_relative() / 1000000.0;
1555 /* compute nominal last_duration */
1556 last_duration = vp_duration(is, lastvp, vp);
1557 delay = compute_target_delay(last_duration, is);
1559 time= av_gettime_relative()/1000000.0;
1560 if (time < is->frame_timer + delay) {
1561 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1565 is->frame_timer += delay;
1566 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1567 is->frame_timer = time;
1569 SDL_LockMutex(is->pictq.mutex);
1570 if (!isnan(vp->pts))
1571 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1572 SDL_UnlockMutex(is->pictq.mutex);
1574 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1575 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1576 duration = vp_duration(is, vp, nextvp);
1577 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1578 is->frame_drops_late++;
1579 frame_queue_next(&is->pictq);
1584 if (is->subtitle_st) {
1585 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1586 sp = frame_queue_peek(&is->subpq);
1588 if (frame_queue_nb_remaining(&is->subpq) > 1)
1589 sp2 = frame_queue_peek_next(&is->subpq);
1593 if (sp->serial != is->subtitleq.serial
1594 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1595 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1599 for (i = 0; i < sp->sub.num_rects; i++) {
1600 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1604 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1605 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1606 memset(pixels, 0, sub_rect->w << 2);
1607 SDL_UnlockTexture(is->sub_texture);
1611 frame_queue_next(&is->subpq);
1618 frame_queue_next(&is->pictq);
1619 is->force_refresh = 1;
1621 if (is->step && !is->paused)
1622 stream_toggle_pause(is);
1625 /* display picture */
1626 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1629 is->force_refresh = 0;
1631 static int64_t last_time;
1633 int aqsize, vqsize, sqsize;
1636 cur_time = av_gettime_relative();
1637 if (!last_time || (cur_time - last_time) >= 30000) {
1642 aqsize = is->audioq.size;
1644 vqsize = is->videoq.size;
1645 if (is->subtitle_st)
1646 sqsize = is->subtitleq.size;
1648 if (is->audio_st && is->video_st)
1649 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1650 else if (is->video_st)
1651 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1652 else if (is->audio_st)
1653 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1654 av_log(NULL, AV_LOG_INFO,
1655 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1656 get_master_clock(is),
1657 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1659 is->frame_drops_early + is->frame_drops_late,
1663 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1664 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1666 last_time = cur_time;
1671 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1675 #if defined(DEBUG_SYNC)
1676 printf("frame_type=%c pts=%0.3f\n",
1677 av_get_picture_type_char(src_frame->pict_type), pts);
1680 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1683 vp->sar = src_frame->sample_aspect_ratio;
1686 vp->width = src_frame->width;
1687 vp->height = src_frame->height;
1688 vp->format = src_frame->format;
1691 vp->duration = duration;
1693 vp->serial = serial;
1695 set_default_window_size(vp->width, vp->height, vp->sar);
1697 av_frame_move_ref(vp->frame, src_frame);
1698 frame_queue_push(&is->pictq);
1702 static int get_video_frame(VideoState *is, AVFrame *frame)
1706 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1712 if (frame->pts != AV_NOPTS_VALUE)
1713 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1715 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1717 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1718 if (frame->pts != AV_NOPTS_VALUE) {
1719 double diff = dpts - get_master_clock(is);
1720 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1721 diff - is->frame_last_filter_delay < 0 &&
1722 is->viddec.pkt_serial == is->vidclk.serial &&
1723 is->videoq.nb_packets) {
1724 is->frame_drops_early++;
1725 av_frame_unref(frame);
1736 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1737 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1740 int nb_filters = graph->nb_filters;
1741 AVFilterInOut *outputs = NULL, *inputs = NULL;
1744 outputs = avfilter_inout_alloc();
1745 inputs = avfilter_inout_alloc();
1746 if (!outputs || !inputs) {
1747 ret = AVERROR(ENOMEM);
1751 outputs->name = av_strdup("in");
1752 outputs->filter_ctx = source_ctx;
1753 outputs->pad_idx = 0;
1754 outputs->next = NULL;
1756 inputs->name = av_strdup("out");
1757 inputs->filter_ctx = sink_ctx;
1758 inputs->pad_idx = 0;
1759 inputs->next = NULL;
1761 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1764 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1768 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1769 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1770 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1772 ret = avfilter_graph_config(graph, NULL);
1774 avfilter_inout_free(&outputs);
1775 avfilter_inout_free(&inputs);
1779 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1781 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1782 char sws_flags_str[512] = "";
1783 char buffersrc_args[256];
1785 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1786 AVCodecParameters *codecpar = is->video_st->codecpar;
1787 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1788 AVDictionaryEntry *e = NULL;
1790 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1791 if (!strcmp(e->key, "sws_flags")) {
1792 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1794 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1796 if (strlen(sws_flags_str))
1797 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1799 graph->scale_sws_opts = av_strdup(sws_flags_str);
1801 snprintf(buffersrc_args, sizeof(buffersrc_args),
1802 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1803 frame->width, frame->height, frame->format,
1804 is->video_st->time_base.num, is->video_st->time_base.den,
1805 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1806 if (fr.num && fr.den)
1807 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1809 if ((ret = avfilter_graph_create_filter(&filt_src,
1810 avfilter_get_by_name("buffer"),
1811 "ffplay_buffer", buffersrc_args, NULL,
1815 ret = avfilter_graph_create_filter(&filt_out,
1816 avfilter_get_by_name("buffersink"),
1817 "ffplay_buffersink", NULL, NULL, graph);
1821 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1824 last_filter = filt_out;
1826 /* Note: this macro adds a filter before the lastly added filter, so the
1827 * processing order of the filters is in reverse */
1828 #define INSERT_FILT(name, arg) do { \
1829 AVFilterContext *filt_ctx; \
1831 ret = avfilter_graph_create_filter(&filt_ctx, \
1832 avfilter_get_by_name(name), \
1833 "ffplay_" name, arg, NULL, graph); \
1837 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1841 last_filter = filt_ctx; \
1845 double theta = get_rotation(is->video_st);
1847 if (fabs(theta - 90) < 1.0) {
1848 INSERT_FILT("transpose", "clock");
1849 } else if (fabs(theta - 180) < 1.0) {
1850 INSERT_FILT("hflip", NULL);
1851 INSERT_FILT("vflip", NULL);
1852 } else if (fabs(theta - 270) < 1.0) {
1853 INSERT_FILT("transpose", "cclock");
1854 } else if (fabs(theta) > 1.0) {
1855 char rotate_buf[64];
1856 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1857 INSERT_FILT("rotate", rotate_buf);
1861 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1864 is->in_video_filter = filt_src;
1865 is->out_video_filter = filt_out;
1871 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1873 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1874 int sample_rates[2] = { 0, -1 };
1875 int64_t channel_layouts[2] = { 0, -1 };
1876 int channels[2] = { 0, -1 };
1877 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1878 char aresample_swr_opts[512] = "";
1879 AVDictionaryEntry *e = NULL;
1880 char asrc_args[256];
1883 avfilter_graph_free(&is->agraph);
1884 if (!(is->agraph = avfilter_graph_alloc()))
1885 return AVERROR(ENOMEM);
1887 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1888 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1889 if (strlen(aresample_swr_opts))
1890 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1891 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1893 ret = snprintf(asrc_args, sizeof(asrc_args),
1894 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1895 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1896 is->audio_filter_src.channels,
1897 1, is->audio_filter_src.freq);
1898 if (is->audio_filter_src.channel_layout)
1899 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1900 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1902 ret = avfilter_graph_create_filter(&filt_asrc,
1903 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1904 asrc_args, NULL, is->agraph);
1909 ret = avfilter_graph_create_filter(&filt_asink,
1910 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1911 NULL, NULL, is->agraph);
1915 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1917 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1920 if (force_output_format) {
1921 channel_layouts[0] = is->audio_tgt.channel_layout;
1922 channels [0] = is->audio_tgt.channels;
1923 sample_rates [0] = is->audio_tgt.freq;
1924 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1926 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1928 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1930 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1935 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1938 is->in_audio_filter = filt_asrc;
1939 is->out_audio_filter = filt_asink;
1943 avfilter_graph_free(&is->agraph);
1946 #endif /* CONFIG_AVFILTER */
1948 static int audio_thread(void *arg)
1950 VideoState *is = arg;
1951 AVFrame *frame = av_frame_alloc();
1954 int last_serial = -1;
1955 int64_t dec_channel_layout;
1963 return AVERROR(ENOMEM);
1966 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1970 tb = (AVRational){1, frame->sample_rate};
1973 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
1976 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
1977 frame->format, av_frame_get_channels(frame)) ||
1978 is->audio_filter_src.channel_layout != dec_channel_layout ||
1979 is->audio_filter_src.freq != frame->sample_rate ||
1980 is->auddec.pkt_serial != last_serial;
1983 char buf1[1024], buf2[1024];
1984 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
1985 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
1986 av_log(NULL, AV_LOG_DEBUG,
1987 "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",
1988 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
1989 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
1991 is->audio_filter_src.fmt = frame->format;
1992 is->audio_filter_src.channels = av_frame_get_channels(frame);
1993 is->audio_filter_src.channel_layout = dec_channel_layout;
1994 is->audio_filter_src.freq = frame->sample_rate;
1995 last_serial = is->auddec.pkt_serial;
1997 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2001 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2004 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2005 tb = av_buffersink_get_time_base(is->out_audio_filter);
2007 if (!(af = frame_queue_peek_writable(&is->sampq)))
2010 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2011 af->pos = av_frame_get_pkt_pos(frame);
2012 af->serial = is->auddec.pkt_serial;
2013 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2015 av_frame_move_ref(af->frame, frame);
2016 frame_queue_push(&is->sampq);
2019 if (is->audioq.serial != is->auddec.pkt_serial)
2022 if (ret == AVERROR_EOF)
2023 is->auddec.finished = is->auddec.pkt_serial;
2026 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2029 avfilter_graph_free(&is->agraph);
2031 av_frame_free(&frame);
2035 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2037 packet_queue_start(d->queue);
2038 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2039 if (!d->decoder_tid) {
2040 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2041 return AVERROR(ENOMEM);
2046 static int video_thread(void *arg)
2048 VideoState *is = arg;
2049 AVFrame *frame = av_frame_alloc();
2053 AVRational tb = is->video_st->time_base;
2054 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2057 AVFilterGraph *graph = avfilter_graph_alloc();
2058 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2061 enum AVPixelFormat last_format = -2;
2062 int last_serial = -1;
2063 int last_vfilter_idx = 0;
2065 av_frame_free(&frame);
2066 return AVERROR(ENOMEM);
2073 avfilter_graph_free(&graph);
2075 return AVERROR(ENOMEM);
2079 ret = get_video_frame(is, frame);
2086 if ( last_w != frame->width
2087 || last_h != frame->height
2088 || last_format != frame->format
2089 || last_serial != is->viddec.pkt_serial
2090 || last_vfilter_idx != is->vfilter_idx) {
2091 av_log(NULL, AV_LOG_DEBUG,
2092 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2094 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2095 frame->width, frame->height,
2096 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2097 avfilter_graph_free(&graph);
2098 graph = avfilter_graph_alloc();
2099 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2101 event.type = FF_QUIT_EVENT;
2102 event.user.data1 = is;
2103 SDL_PushEvent(&event);
2106 filt_in = is->in_video_filter;
2107 filt_out = is->out_video_filter;
2108 last_w = frame->width;
2109 last_h = frame->height;
2110 last_format = frame->format;
2111 last_serial = is->viddec.pkt_serial;
2112 last_vfilter_idx = is->vfilter_idx;
2113 frame_rate = av_buffersink_get_frame_rate(filt_out);
2116 ret = av_buffersrc_add_frame(filt_in, frame);
2121 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2123 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2125 if (ret == AVERROR_EOF)
2126 is->viddec.finished = is->viddec.pkt_serial;
2131 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2132 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2133 is->frame_last_filter_delay = 0;
2134 tb = av_buffersink_get_time_base(filt_out);
2136 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2137 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2138 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2139 av_frame_unref(frame);
2149 avfilter_graph_free(&graph);
2151 av_frame_free(&frame);
2155 static int subtitle_thread(void *arg)
2157 VideoState *is = arg;
2163 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2166 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2171 if (got_subtitle && sp->sub.format == 0) {
2172 if (sp->sub.pts != AV_NOPTS_VALUE)
2173 pts = sp->sub.pts / (double)AV_TIME_BASE;
2175 sp->serial = is->subdec.pkt_serial;
2176 sp->width = is->subdec.avctx->width;
2177 sp->height = is->subdec.avctx->height;
2180 /* now we can update the picture count */
2181 frame_queue_push(&is->subpq);
2182 } else if (got_subtitle) {
2183 avsubtitle_free(&sp->sub);
2189 /* copy samples for viewing in editor window */
2190 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2194 size = samples_size / sizeof(short);
2196 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2199 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2201 is->sample_array_index += len;
2202 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2203 is->sample_array_index = 0;
2208 /* return the wanted number of samples to get better sync if sync_type is video
2209 * or external master clock */
2210 static int synchronize_audio(VideoState *is, int nb_samples)
2212 int wanted_nb_samples = nb_samples;
2214 /* if not master, then we try to remove or add samples to correct the clock */
2215 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2216 double diff, avg_diff;
2217 int min_nb_samples, max_nb_samples;
2219 diff = get_clock(&is->audclk) - get_master_clock(is);
2221 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2222 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2223 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2224 /* not enough measures to have a correct estimate */
2225 is->audio_diff_avg_count++;
2227 /* estimate the A-V difference */
2228 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2230 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2231 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2232 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2233 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2234 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2236 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2237 diff, avg_diff, wanted_nb_samples - nb_samples,
2238 is->audio_clock, is->audio_diff_threshold);
2241 /* too big difference : may be initial PTS errors, so
2243 is->audio_diff_avg_count = 0;
2244 is->audio_diff_cum = 0;
2248 return wanted_nb_samples;
2252 * Decode one audio frame and return its uncompressed size.
2254 * The processed audio frame is decoded, converted if required, and
2255 * stored in is->audio_buf, with size in bytes given by the return
2258 static int audio_decode_frame(VideoState *is)
2260 int data_size, resampled_data_size;
2261 int64_t dec_channel_layout;
2262 av_unused double audio_clock0;
2263 int wanted_nb_samples;
2271 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2272 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2277 if (!(af = frame_queue_peek_readable(&is->sampq)))
2279 frame_queue_next(&is->sampq);
2280 } while (af->serial != is->audioq.serial);
2282 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2283 af->frame->nb_samples,
2284 af->frame->format, 1);
2286 dec_channel_layout =
2287 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2288 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2289 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2291 if (af->frame->format != is->audio_src.fmt ||
2292 dec_channel_layout != is->audio_src.channel_layout ||
2293 af->frame->sample_rate != is->audio_src.freq ||
2294 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2295 swr_free(&is->swr_ctx);
2296 is->swr_ctx = swr_alloc_set_opts(NULL,
2297 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2298 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2300 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2301 av_log(NULL, AV_LOG_ERROR,
2302 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2303 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2304 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2305 swr_free(&is->swr_ctx);
2308 is->audio_src.channel_layout = dec_channel_layout;
2309 is->audio_src.channels = av_frame_get_channels(af->frame);
2310 is->audio_src.freq = af->frame->sample_rate;
2311 is->audio_src.fmt = af->frame->format;
2315 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2316 uint8_t **out = &is->audio_buf1;
2317 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2318 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2321 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2324 if (wanted_nb_samples != af->frame->nb_samples) {
2325 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2326 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2327 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2331 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2332 if (!is->audio_buf1)
2333 return AVERROR(ENOMEM);
2334 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2336 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2339 if (len2 == out_count) {
2340 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2341 if (swr_init(is->swr_ctx) < 0)
2342 swr_free(&is->swr_ctx);
2344 is->audio_buf = is->audio_buf1;
2345 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2347 is->audio_buf = af->frame->data[0];
2348 resampled_data_size = data_size;
2351 audio_clock0 = is->audio_clock;
2352 /* update the audio clock with the pts */
2353 if (!isnan(af->pts))
2354 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2356 is->audio_clock = NAN;
2357 is->audio_clock_serial = af->serial;
2360 static double last_clock;
2361 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2362 is->audio_clock - last_clock,
2363 is->audio_clock, audio_clock0);
2364 last_clock = is->audio_clock;
2367 return resampled_data_size;
2370 /* prepare a new audio buffer */
2371 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2373 VideoState *is = opaque;
2374 int audio_size, len1;
2376 audio_callback_time = av_gettime_relative();
2379 if (is->audio_buf_index >= is->audio_buf_size) {
2380 audio_size = audio_decode_frame(is);
2381 if (audio_size < 0) {
2382 /* if error, just output silence */
2383 is->audio_buf = NULL;
2384 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2386 if (is->show_mode != SHOW_MODE_VIDEO)
2387 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2388 is->audio_buf_size = audio_size;
2390 is->audio_buf_index = 0;
2392 len1 = is->audio_buf_size - is->audio_buf_index;
2395 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2396 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2398 memset(stream, 0, len1);
2399 if (!is->muted && is->audio_buf)
2400 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2404 is->audio_buf_index += len1;
2406 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2407 /* Let's assume the audio driver that is used by SDL has two periods. */
2408 if (!isnan(is->audio_clock)) {
2409 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);
2410 sync_clock_to_slave(&is->extclk, &is->audclk);
2414 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2416 SDL_AudioSpec wanted_spec, spec;
2418 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2419 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2420 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2422 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2424 wanted_nb_channels = atoi(env);
2425 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2427 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2428 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2429 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2431 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2432 wanted_spec.channels = wanted_nb_channels;
2433 wanted_spec.freq = wanted_sample_rate;
2434 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2435 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2438 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2439 next_sample_rate_idx--;
2440 wanted_spec.format = AUDIO_S16SYS;
2441 wanted_spec.silence = 0;
2442 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2443 wanted_spec.callback = sdl_audio_callback;
2444 wanted_spec.userdata = opaque;
2445 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2446 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2447 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2448 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2449 if (!wanted_spec.channels) {
2450 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2451 wanted_spec.channels = wanted_nb_channels;
2452 if (!wanted_spec.freq) {
2453 av_log(NULL, AV_LOG_ERROR,
2454 "No more combinations to try, audio open failed\n");
2458 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2460 if (spec.format != AUDIO_S16SYS) {
2461 av_log(NULL, AV_LOG_ERROR,
2462 "SDL advised audio format %d is not supported!\n", spec.format);
2465 if (spec.channels != wanted_spec.channels) {
2466 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2467 if (!wanted_channel_layout) {
2468 av_log(NULL, AV_LOG_ERROR,
2469 "SDL advised channel count %d is not supported!\n", spec.channels);
2474 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2475 audio_hw_params->freq = spec.freq;
2476 audio_hw_params->channel_layout = wanted_channel_layout;
2477 audio_hw_params->channels = spec.channels;
2478 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2479 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);
2480 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2481 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2487 /* open a given stream. Return 0 if OK */
2488 static int stream_component_open(VideoState *is, int stream_index)
2490 AVFormatContext *ic = is->ic;
2491 AVCodecContext *avctx;
2493 const char *forced_codec_name = NULL;
2494 AVDictionary *opts = NULL;
2495 AVDictionaryEntry *t = NULL;
2496 int sample_rate, nb_channels;
2497 int64_t channel_layout;
2499 int stream_lowres = lowres;
2501 if (stream_index < 0 || stream_index >= ic->nb_streams)
2504 avctx = avcodec_alloc_context3(NULL);
2506 return AVERROR(ENOMEM);
2508 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2511 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2513 codec = avcodec_find_decoder(avctx->codec_id);
2515 switch(avctx->codec_type){
2516 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2517 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2518 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2520 if (forced_codec_name)
2521 codec = avcodec_find_decoder_by_name(forced_codec_name);
2523 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2524 "No codec could be found with name '%s'\n", forced_codec_name);
2525 else av_log(NULL, AV_LOG_WARNING,
2526 "No codec could be found with id %d\n", avctx->codec_id);
2527 ret = AVERROR(EINVAL);
2531 avctx->codec_id = codec->id;
2532 if(stream_lowres > av_codec_get_max_lowres(codec)){
2533 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2534 av_codec_get_max_lowres(codec));
2535 stream_lowres = av_codec_get_max_lowres(codec);
2537 av_codec_set_lowres(avctx, stream_lowres);
2540 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2543 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2545 if(codec->capabilities & AV_CODEC_CAP_DR1)
2546 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2549 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2550 if (!av_dict_get(opts, "threads", NULL, 0))
2551 av_dict_set(&opts, "threads", "auto", 0);
2553 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2554 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2555 av_dict_set(&opts, "refcounted_frames", "1", 0);
2556 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2559 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2560 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2561 ret = AVERROR_OPTION_NOT_FOUND;
2566 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2567 switch (avctx->codec_type) {
2568 case AVMEDIA_TYPE_AUDIO:
2571 AVFilterContext *sink;
2573 is->audio_filter_src.freq = avctx->sample_rate;
2574 is->audio_filter_src.channels = avctx->channels;
2575 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2576 is->audio_filter_src.fmt = avctx->sample_fmt;
2577 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2579 sink = is->out_audio_filter;
2580 sample_rate = av_buffersink_get_sample_rate(sink);
2581 nb_channels = av_buffersink_get_channels(sink);
2582 channel_layout = av_buffersink_get_channel_layout(sink);
2585 sample_rate = avctx->sample_rate;
2586 nb_channels = avctx->channels;
2587 channel_layout = avctx->channel_layout;
2590 /* prepare audio output */
2591 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2593 is->audio_hw_buf_size = ret;
2594 is->audio_src = is->audio_tgt;
2595 is->audio_buf_size = 0;
2596 is->audio_buf_index = 0;
2598 /* init averaging filter */
2599 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2600 is->audio_diff_avg_count = 0;
2601 /* since we do not have a precise anough audio FIFO fullness,
2602 we correct audio sync only if larger than this threshold */
2603 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2605 is->audio_stream = stream_index;
2606 is->audio_st = ic->streams[stream_index];
2608 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2609 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2610 is->auddec.start_pts = is->audio_st->start_time;
2611 is->auddec.start_pts_tb = is->audio_st->time_base;
2613 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2617 case AVMEDIA_TYPE_VIDEO:
2618 is->video_stream = stream_index;
2619 is->video_st = ic->streams[stream_index];
2621 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2622 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2624 is->queue_attachments_req = 1;
2626 case AVMEDIA_TYPE_SUBTITLE:
2627 is->subtitle_stream = stream_index;
2628 is->subtitle_st = ic->streams[stream_index];
2630 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2631 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2640 avcodec_free_context(&avctx);
2642 av_dict_free(&opts);
2647 static int decode_interrupt_cb(void *ctx)
2649 VideoState *is = ctx;
2650 return is->abort_request;
2653 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2654 return stream_id < 0 ||
2655 queue->abort_request ||
2656 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2657 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2660 static int is_realtime(AVFormatContext *s)
2662 if( !strcmp(s->iformat->name, "rtp")
2663 || !strcmp(s->iformat->name, "rtsp")
2664 || !strcmp(s->iformat->name, "sdp")
2668 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2669 || !strncmp(s->filename, "udp:", 4)
2676 /* this thread gets the stream from the disk or the network */
2677 static int read_thread(void *arg)
2679 VideoState *is = arg;
2680 AVFormatContext *ic = NULL;
2682 int st_index[AVMEDIA_TYPE_NB];
2683 AVPacket pkt1, *pkt = &pkt1;
2684 int64_t stream_start_time;
2685 int pkt_in_play_range = 0;
2686 AVDictionaryEntry *t;
2687 AVDictionary **opts;
2688 int orig_nb_streams;
2689 SDL_mutex *wait_mutex = SDL_CreateMutex();
2690 int scan_all_pmts_set = 0;
2694 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2695 ret = AVERROR(ENOMEM);
2699 memset(st_index, -1, sizeof(st_index));
2700 is->last_video_stream = is->video_stream = -1;
2701 is->last_audio_stream = is->audio_stream = -1;
2702 is->last_subtitle_stream = is->subtitle_stream = -1;
2705 ic = avformat_alloc_context();
2707 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2708 ret = AVERROR(ENOMEM);
2711 ic->interrupt_callback.callback = decode_interrupt_cb;
2712 ic->interrupt_callback.opaque = is;
2713 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2714 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2715 scan_all_pmts_set = 1;
2717 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2719 print_error(is->filename, err);
2723 if (scan_all_pmts_set)
2724 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2726 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2727 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2728 ret = AVERROR_OPTION_NOT_FOUND;
2734 ic->flags |= AVFMT_FLAG_GENPTS;
2736 av_format_inject_global_side_data(ic);
2738 opts = setup_find_stream_info_opts(ic, codec_opts);
2739 orig_nb_streams = ic->nb_streams;
2741 err = avformat_find_stream_info(ic, opts);
2743 for (i = 0; i < orig_nb_streams; i++)
2744 av_dict_free(&opts[i]);
2748 av_log(NULL, AV_LOG_WARNING,
2749 "%s: could not find codec parameters\n", is->filename);
2755 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2757 if (seek_by_bytes < 0)
2758 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2760 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2762 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2763 window_title = av_asprintf("%s - %s", t->value, input_filename);
2765 /* if seeking requested, we execute it */
2766 if (start_time != AV_NOPTS_VALUE) {
2769 timestamp = start_time;
2770 /* add the stream start time */
2771 if (ic->start_time != AV_NOPTS_VALUE)
2772 timestamp += ic->start_time;
2773 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2775 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2776 is->filename, (double)timestamp / AV_TIME_BASE);
2780 is->realtime = is_realtime(ic);
2783 av_dump_format(ic, 0, is->filename, 0);
2785 for (i = 0; i < ic->nb_streams; i++) {
2786 AVStream *st = ic->streams[i];
2787 enum AVMediaType type = st->codecpar->codec_type;
2788 st->discard = AVDISCARD_ALL;
2789 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2790 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2793 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2794 if (wanted_stream_spec[i] && st_index[i] == -1) {
2795 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));
2796 st_index[i] = INT_MAX;
2801 st_index[AVMEDIA_TYPE_VIDEO] =
2802 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2803 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2805 st_index[AVMEDIA_TYPE_AUDIO] =
2806 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2807 st_index[AVMEDIA_TYPE_AUDIO],
2808 st_index[AVMEDIA_TYPE_VIDEO],
2810 if (!video_disable && !subtitle_disable)
2811 st_index[AVMEDIA_TYPE_SUBTITLE] =
2812 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2813 st_index[AVMEDIA_TYPE_SUBTITLE],
2814 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2815 st_index[AVMEDIA_TYPE_AUDIO] :
2816 st_index[AVMEDIA_TYPE_VIDEO]),
2819 is->show_mode = show_mode;
2820 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2821 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2822 AVCodecParameters *codecpar = st->codecpar;
2823 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2824 if (codecpar->width)
2825 set_default_window_size(codecpar->width, codecpar->height, sar);
2828 /* open the streams */
2829 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2830 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2834 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2835 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2837 if (is->show_mode == SHOW_MODE_NONE)
2838 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2840 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2841 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2844 if (is->video_stream < 0 && is->audio_stream < 0) {
2845 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2851 if (infinite_buffer < 0 && is->realtime)
2852 infinite_buffer = 1;
2855 if (is->abort_request)
2857 if (is->paused != is->last_paused) {
2858 is->last_paused = is->paused;
2860 is->read_pause_return = av_read_pause(ic);
2864 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2866 (!strcmp(ic->iformat->name, "rtsp") ||
2867 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2868 /* wait 10 ms to avoid trying to get another packet */
2875 int64_t seek_target = is->seek_pos;
2876 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2877 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2878 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2879 // of the seek_pos/seek_rel variables
2881 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2883 av_log(NULL, AV_LOG_ERROR,
2884 "%s: error while seeking\n", is->ic->filename);
2886 if (is->audio_stream >= 0) {
2887 packet_queue_flush(&is->audioq);
2888 packet_queue_put(&is->audioq, &flush_pkt);
2890 if (is->subtitle_stream >= 0) {
2891 packet_queue_flush(&is->subtitleq);
2892 packet_queue_put(&is->subtitleq, &flush_pkt);
2894 if (is->video_stream >= 0) {
2895 packet_queue_flush(&is->videoq);
2896 packet_queue_put(&is->videoq, &flush_pkt);
2898 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2899 set_clock(&is->extclk, NAN, 0);
2901 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2905 is->queue_attachments_req = 1;
2908 step_to_next_frame(is);
2910 if (is->queue_attachments_req) {
2911 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2913 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2915 packet_queue_put(&is->videoq, ©);
2916 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2918 is->queue_attachments_req = 0;
2921 /* if the queue are full, no need to read more */
2922 if (infinite_buffer<1 &&
2923 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2924 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2925 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2926 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2928 SDL_LockMutex(wait_mutex);
2929 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2930 SDL_UnlockMutex(wait_mutex);
2934 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2935 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2936 if (loop != 1 && (!loop || --loop)) {
2937 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2938 } else if (autoexit) {
2943 ret = av_read_frame(ic, pkt);
2945 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
2946 if (is->video_stream >= 0)
2947 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2948 if (is->audio_stream >= 0)
2949 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2950 if (is->subtitle_stream >= 0)
2951 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
2954 if (ic->pb && ic->pb->error)
2956 SDL_LockMutex(wait_mutex);
2957 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2958 SDL_UnlockMutex(wait_mutex);
2963 /* check if packet is in play range specified by user, then queue, otherwise discard */
2964 stream_start_time = ic->streams[pkt->stream_index]->start_time;
2965 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
2966 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2967 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
2968 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2969 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2970 <= ((double)duration / 1000000);
2971 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2972 packet_queue_put(&is->audioq, pkt);
2973 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2974 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
2975 packet_queue_put(&is->videoq, pkt);
2976 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2977 packet_queue_put(&is->subtitleq, pkt);
2979 av_packet_unref(pkt);
2986 avformat_close_input(&ic);
2991 event.type = FF_QUIT_EVENT;
2992 event.user.data1 = is;
2993 SDL_PushEvent(&event);
2995 SDL_DestroyMutex(wait_mutex);
2999 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3003 is = av_mallocz(sizeof(VideoState));
3006 is->filename = av_strdup(filename);
3009 is->iformat = iformat;
3013 /* start video display */
3014 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3016 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3018 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3021 if (packet_queue_init(&is->videoq) < 0 ||
3022 packet_queue_init(&is->audioq) < 0 ||
3023 packet_queue_init(&is->subtitleq) < 0)
3026 if (!(is->continue_read_thread = SDL_CreateCond())) {
3027 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3031 init_clock(&is->vidclk, &is->videoq.serial);
3032 init_clock(&is->audclk, &is->audioq.serial);
3033 init_clock(&is->extclk, &is->extclk.serial);
3034 is->audio_clock_serial = -1;
3035 if (startup_volume < 0)
3036 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3037 if (startup_volume > 100)
3038 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3039 startup_volume = av_clip(startup_volume, 0, 100);
3040 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3041 is->audio_volume = startup_volume;
3043 is->av_sync_type = av_sync_type;
3044 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3045 if (!is->read_tid) {
3046 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3054 static void stream_cycle_channel(VideoState *is, int codec_type)
3056 AVFormatContext *ic = is->ic;
3057 int start_index, stream_index;
3060 AVProgram *p = NULL;
3061 int nb_streams = is->ic->nb_streams;
3063 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3064 start_index = is->last_video_stream;
3065 old_index = is->video_stream;
3066 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3067 start_index = is->last_audio_stream;
3068 old_index = is->audio_stream;
3070 start_index = is->last_subtitle_stream;
3071 old_index = is->subtitle_stream;
3073 stream_index = start_index;
3075 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3076 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3078 nb_streams = p->nb_stream_indexes;
3079 for (start_index = 0; start_index < nb_streams; start_index++)
3080 if (p->stream_index[start_index] == stream_index)
3082 if (start_index == nb_streams)
3084 stream_index = start_index;
3089 if (++stream_index >= nb_streams)
3091 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3094 is->last_subtitle_stream = -1;
3097 if (start_index == -1)
3101 if (stream_index == start_index)
3103 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3104 if (st->codecpar->codec_type == codec_type) {
3105 /* check that parameters are OK */
3106 switch (codec_type) {
3107 case AVMEDIA_TYPE_AUDIO:
3108 if (st->codecpar->sample_rate != 0 &&
3109 st->codecpar->channels != 0)
3112 case AVMEDIA_TYPE_VIDEO:
3113 case AVMEDIA_TYPE_SUBTITLE:
3121 if (p && stream_index != -1)
3122 stream_index = p->stream_index[stream_index];
3123 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3124 av_get_media_type_string(codec_type),
3128 stream_component_close(is, old_index);
3129 stream_component_open(is, stream_index);
3133 static void toggle_full_screen(VideoState *is)
3135 is_full_screen = !is_full_screen;
3136 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3139 static void toggle_audio_display(VideoState *is)
3141 int next = is->show_mode;
3143 next = (next + 1) % SHOW_MODE_NB;
3144 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3145 if (is->show_mode != next) {
3146 is->force_refresh = 1;
3147 is->show_mode = next;
3151 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3152 double remaining_time = 0.0;
3154 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3155 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3159 if (remaining_time > 0.0)
3160 av_usleep((int64_t)(remaining_time * 1000000.0));
3161 remaining_time = REFRESH_RATE;
3162 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3163 video_refresh(is, &remaining_time);
3168 static void seek_chapter(VideoState *is, int incr)
3170 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3173 if (!is->ic->nb_chapters)
3176 /* find the current chapter */
3177 for (i = 0; i < is->ic->nb_chapters; i++) {
3178 AVChapter *ch = is->ic->chapters[i];
3179 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3187 if (i >= is->ic->nb_chapters)
3190 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3191 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3192 AV_TIME_BASE_Q), 0, 0);
3195 /* handle an event sent by the GUI */
3196 static void event_loop(VideoState *cur_stream)
3199 double incr, pos, frac;
3203 refresh_loop_wait_event(cur_stream, &event);
3204 switch (event.type) {
3206 if (exit_on_keydown) {
3207 do_exit(cur_stream);
3210 switch (event.key.keysym.sym) {
3213 do_exit(cur_stream);
3216 toggle_full_screen(cur_stream);
3217 cur_stream->force_refresh = 1;
3221 toggle_pause(cur_stream);
3224 toggle_mute(cur_stream);
3226 case SDLK_KP_MULTIPLY:
3228 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3230 case SDLK_KP_DIVIDE:
3232 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3234 case SDLK_s: // S: Step to next frame
3235 step_to_next_frame(cur_stream);
3238 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3241 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3244 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3245 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3246 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3249 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3253 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3254 if (++cur_stream->vfilter_idx >= nb_vfilters)
3255 cur_stream->vfilter_idx = 0;
3257 cur_stream->vfilter_idx = 0;
3258 toggle_audio_display(cur_stream);
3261 toggle_audio_display(cur_stream);
3265 if (cur_stream->ic->nb_chapters <= 1) {
3269 seek_chapter(cur_stream, 1);
3272 if (cur_stream->ic->nb_chapters <= 1) {
3276 seek_chapter(cur_stream, -1);
3290 if (seek_by_bytes) {
3292 if (pos < 0 && cur_stream->video_stream >= 0)
3293 pos = frame_queue_last_pos(&cur_stream->pictq);
3294 if (pos < 0 && cur_stream->audio_stream >= 0)
3295 pos = frame_queue_last_pos(&cur_stream->sampq);
3297 pos = avio_tell(cur_stream->ic->pb);
3298 if (cur_stream->ic->bit_rate)
3299 incr *= cur_stream->ic->bit_rate / 8.0;
3303 stream_seek(cur_stream, pos, incr, 1);
3305 pos = get_master_clock(cur_stream);
3307 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3309 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3310 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3311 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3318 case SDL_MOUSEBUTTONDOWN:
3319 if (exit_on_mousedown) {
3320 do_exit(cur_stream);
3323 if (event.button.button == SDL_BUTTON_LEFT) {
3324 static int64_t last_mouse_left_click = 0;
3325 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3326 toggle_full_screen(cur_stream);
3327 cur_stream->force_refresh = 1;
3328 last_mouse_left_click = 0;
3330 last_mouse_left_click = av_gettime_relative();
3333 case SDL_MOUSEMOTION:
3334 if (cursor_hidden) {
3338 cursor_last_shown = av_gettime_relative();
3339 if (event.type == SDL_MOUSEBUTTONDOWN) {
3340 if (event.button.button != SDL_BUTTON_RIGHT)
3344 if (!(event.motion.state & SDL_BUTTON_RMASK))
3348 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3349 uint64_t size = avio_size(cur_stream->ic->pb);
3350 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3354 int tns, thh, tmm, tss;
3355 tns = cur_stream->ic->duration / 1000000LL;
3357 tmm = (tns % 3600) / 60;
3359 frac = x / cur_stream->width;
3362 mm = (ns % 3600) / 60;
3364 av_log(NULL, AV_LOG_INFO,
3365 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3366 hh, mm, ss, thh, tmm, tss);
3367 ts = frac * cur_stream->ic->duration;
3368 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3369 ts += cur_stream->ic->start_time;
3370 stream_seek(cur_stream, ts, 0, 0);
3373 case SDL_WINDOWEVENT:
3374 switch (event.window.event) {
3375 case SDL_WINDOWEVENT_RESIZED:
3376 screen_width = cur_stream->width = event.window.data1;
3377 screen_height = cur_stream->height = event.window.data2;
3378 if (cur_stream->vis_texture) {
3379 SDL_DestroyTexture(cur_stream->vis_texture);
3380 cur_stream->vis_texture = NULL;
3382 case SDL_WINDOWEVENT_EXPOSED:
3383 cur_stream->force_refresh = 1;
3388 do_exit(cur_stream);
3396 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3398 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3399 return opt_default(NULL, "video_size", arg);
3402 static int opt_width(void *optctx, const char *opt, const char *arg)
3404 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3408 static int opt_height(void *optctx, const char *opt, const char *arg)
3410 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3414 static int opt_format(void *optctx, const char *opt, const char *arg)
3416 file_iformat = av_find_input_format(arg);
3417 if (!file_iformat) {
3418 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3419 return AVERROR(EINVAL);
3424 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3426 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3427 return opt_default(NULL, "pixel_format", arg);
3430 static int opt_sync(void *optctx, const char *opt, const char *arg)
3432 if (!strcmp(arg, "audio"))
3433 av_sync_type = AV_SYNC_AUDIO_MASTER;
3434 else if (!strcmp(arg, "video"))
3435 av_sync_type = AV_SYNC_VIDEO_MASTER;
3436 else if (!strcmp(arg, "ext"))
3437 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3439 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3445 static int opt_seek(void *optctx, const char *opt, const char *arg)
3447 start_time = parse_time_or_die(opt, arg, 1);
3451 static int opt_duration(void *optctx, const char *opt, const char *arg)
3453 duration = parse_time_or_die(opt, arg, 1);
3457 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3459 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3460 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3461 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3462 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3466 static void opt_input_file(void *optctx, const char *filename)
3468 if (input_filename) {
3469 av_log(NULL, AV_LOG_FATAL,
3470 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3471 filename, input_filename);
3474 if (!strcmp(filename, "-"))
3476 input_filename = filename;
3479 static int opt_codec(void *optctx, const char *opt, const char *arg)
3481 const char *spec = strchr(opt, ':');
3483 av_log(NULL, AV_LOG_ERROR,
3484 "No media specifier was specified in '%s' in option '%s'\n",
3486 return AVERROR(EINVAL);
3490 case 'a' : audio_codec_name = arg; break;
3491 case 's' : subtitle_codec_name = arg; break;
3492 case 'v' : video_codec_name = arg; break;
3494 av_log(NULL, AV_LOG_ERROR,
3495 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3496 return AVERROR(EINVAL);
3503 static const OptionDef options[] = {
3504 #include "cmdutils_common_opts.h"
3505 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3506 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3507 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3508 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3509 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3510 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3511 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3512 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3513 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3514 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3515 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3516 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3517 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3518 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3519 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3520 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3521 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3522 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3523 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3524 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3525 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3526 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3527 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3528 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3529 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3530 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3531 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3532 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3533 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3534 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3535 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3537 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3538 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3540 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3541 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3542 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3543 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3544 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3545 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3546 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3547 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3548 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3552 static void show_usage(void)
3554 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3555 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3556 av_log(NULL, AV_LOG_INFO, "\n");
3559 void show_help_default(const char *opt, const char *arg)
3561 av_log_set_callback(log_callback_help);
3563 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3564 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3566 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3567 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3568 #if !CONFIG_AVFILTER
3569 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3571 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3573 printf("\nWhile playing:\n"
3575 "f toggle full screen\n"
3578 "9, 0 decrease and increase volume respectively\n"
3579 "/, * decrease and increase volume respectively\n"
3580 "a cycle audio channel in the current program\n"
3581 "v cycle video channel\n"
3582 "t cycle subtitle channel in the current program\n"
3584 "w cycle video filters or show modes\n"
3585 "s activate frame-step mode\n"
3586 "left/right seek backward/forward 10 seconds\n"
3587 "down/up seek backward/forward 1 minute\n"
3588 "page down/page up seek backward/forward 10 minutes\n"
3589 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3590 "left double-click toggle full screen\n"
3594 static int lockmgr(void **mtx, enum AVLockOp op)
3597 case AV_LOCK_CREATE:
3598 *mtx = SDL_CreateMutex();
3600 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3604 case AV_LOCK_OBTAIN:
3605 return !!SDL_LockMutex(*mtx);
3606 case AV_LOCK_RELEASE:
3607 return !!SDL_UnlockMutex(*mtx);
3608 case AV_LOCK_DESTROY:
3609 SDL_DestroyMutex(*mtx);
3615 /* Called from the main */
3616 int main(int argc, char **argv)
3623 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3624 parse_loglevel(argc, argv, options);
3626 /* register all codecs, demux and protocols */
3628 avdevice_register_all();
3631 avfilter_register_all();
3634 avformat_network_init();
3638 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3639 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3641 show_banner(argc, argv, options);
3643 parse_options(NULL, argc, argv, options, opt_input_file);
3645 if (!input_filename) {
3647 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3648 av_log(NULL, AV_LOG_FATAL,
3649 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3653 if (display_disable) {
3656 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3658 flags &= ~SDL_INIT_AUDIO;
3660 /* Try to work around an occasional ALSA buffer underflow issue when the
3661 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3662 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3663 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3665 if (display_disable)
3666 flags &= ~SDL_INIT_VIDEO;
3667 if (SDL_Init (flags)) {
3668 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3669 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3673 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3674 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3676 if (av_lockmgr_register(lockmgr)) {
3677 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3681 av_init_packet(&flush_pkt);
3682 flush_pkt.data = (uint8_t *)&flush_pkt;
3684 is = stream_open(input_filename, file_iformat);
3686 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");