2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
110 static unsigned sws_flags = SWS_BICUBIC;
112 typedef struct MyAVPacketList {
114 struct MyAVPacketList *next;
118 typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
134 typedef struct AudioParams {
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
143 typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
148 int serial; /* clock is based on a packet with this serial */
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
171 typedef struct FrameQueue {
172 Frame queue[FRAME_QUEUE_SIZE];
185 AV_SYNC_AUDIO_MASTER, /* default choice */
186 AV_SYNC_VIDEO_MASTER,
187 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
190 typedef struct Decoder {
194 AVCodecContext *avctx;
198 SDL_cond *empty_queue_cond;
200 AVRational start_pts_tb;
202 AVRational next_pts_tb;
203 SDL_Thread *decoder_tid;
206 typedef struct VideoState {
207 SDL_Thread *read_tid;
208 AVInputFormat *iformat;
213 int queue_attachments_req;
218 int read_pause_return;
239 int audio_clock_serial;
240 double audio_diff_cum; /* used for AV difference average computation */
241 double audio_diff_avg_coef;
242 double audio_diff_threshold;
243 int audio_diff_avg_count;
246 int audio_hw_buf_size;
249 unsigned int audio_buf_size; /* in bytes */
250 unsigned int audio_buf1_size;
251 int audio_buf_index; /* in bytes */
252 int audio_write_buf_size;
255 struct AudioParams audio_src;
257 struct AudioParams audio_filter_src;
259 struct AudioParams audio_tgt;
260 struct SwrContext *swr_ctx;
261 int frame_drops_early;
262 int frame_drops_late;
265 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
267 int16_t sample_array[SAMPLE_ARRAY_SIZE];
268 int sample_array_index;
272 FFTSample *rdft_data;
274 double last_vis_time;
275 SDL_Texture *vis_texture;
276 SDL_Texture *sub_texture;
279 AVStream *subtitle_st;
280 PacketQueue subtitleq;
283 double frame_last_returned_time;
284 double frame_last_filter_delay;
288 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
289 struct SwsContext *img_convert_ctx;
290 struct SwsContext *sub_convert_ctx;
294 int width, height, xleft, ytop;
299 AVFilterContext *in_video_filter; // the first filter in the video chain
300 AVFilterContext *out_video_filter; // the last filter in the video chain
301 AVFilterContext *in_audio_filter; // the first filter in the audio chain
302 AVFilterContext *out_audio_filter; // the last filter in the audio chain
303 AVFilterGraph *agraph; // audio filter graph
306 int last_video_stream, last_audio_stream, last_subtitle_stream;
308 SDL_cond *continue_read_thread;
311 /* options specified by the user */
312 static AVInputFormat *file_iformat;
313 static const char *input_filename;
314 static const char *window_title;
315 static int default_width = 640;
316 static int default_height = 480;
317 static int screen_width = 0;
318 static int screen_height = 0;
319 static int audio_disable;
320 static int video_disable;
321 static int subtitle_disable;
322 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
323 static int seek_by_bytes = -1;
324 static int display_disable;
325 static int 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_ALLOC_EVENT (SDL_USEREVENT)
361 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
363 static SDL_Window *window;
364 static SDL_Renderer *renderer;
367 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
369 GROW_ARRAY(vfilters_list, nb_vfilters);
370 vfilters_list[nb_vfilters - 1] = arg;
376 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
377 enum AVSampleFormat fmt2, int64_t channel_count2)
379 /* If channel count == 1, planar and non-planar formats are the same */
380 if (channel_count1 == 1 && channel_count2 == 1)
381 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
383 return channel_count1 != channel_count2 || fmt1 != fmt2;
387 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
389 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
390 return channel_layout;
395 static void free_picture(Frame *vp);
397 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
399 MyAVPacketList *pkt1;
401 if (q->abort_request)
404 pkt1 = av_malloc(sizeof(MyAVPacketList));
409 if (pkt == &flush_pkt)
411 pkt1->serial = q->serial;
416 q->last_pkt->next = pkt1;
419 q->size += pkt1->pkt.size + sizeof(*pkt1);
420 q->duration += pkt1->pkt.duration;
421 /* XXX: should duplicate packet data in DV case */
422 SDL_CondSignal(q->cond);
426 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
430 SDL_LockMutex(q->mutex);
431 ret = packet_queue_put_private(q, pkt);
432 SDL_UnlockMutex(q->mutex);
434 if (pkt != &flush_pkt && ret < 0)
435 av_packet_unref(pkt);
440 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
442 AVPacket pkt1, *pkt = &pkt1;
446 pkt->stream_index = stream_index;
447 return packet_queue_put(q, pkt);
450 /* packet queue handling */
451 static int packet_queue_init(PacketQueue *q)
453 memset(q, 0, sizeof(PacketQueue));
454 q->mutex = SDL_CreateMutex();
456 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
457 return AVERROR(ENOMEM);
459 q->cond = SDL_CreateCond();
461 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
462 return AVERROR(ENOMEM);
464 q->abort_request = 1;
468 static void packet_queue_flush(PacketQueue *q)
470 MyAVPacketList *pkt, *pkt1;
472 SDL_LockMutex(q->mutex);
473 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
475 av_packet_unref(&pkt->pkt);
483 SDL_UnlockMutex(q->mutex);
486 static void packet_queue_destroy(PacketQueue *q)
488 packet_queue_flush(q);
489 SDL_DestroyMutex(q->mutex);
490 SDL_DestroyCond(q->cond);
493 static void packet_queue_abort(PacketQueue *q)
495 SDL_LockMutex(q->mutex);
497 q->abort_request = 1;
499 SDL_CondSignal(q->cond);
501 SDL_UnlockMutex(q->mutex);
504 static void packet_queue_start(PacketQueue *q)
506 SDL_LockMutex(q->mutex);
507 q->abort_request = 0;
508 packet_queue_put_private(q, &flush_pkt);
509 SDL_UnlockMutex(q->mutex);
512 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
513 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
515 MyAVPacketList *pkt1;
518 SDL_LockMutex(q->mutex);
521 if (q->abort_request) {
528 q->first_pkt = pkt1->next;
532 q->size -= pkt1->pkt.size + sizeof(*pkt1);
533 q->duration -= pkt1->pkt.duration;
536 *serial = pkt1->serial;
544 SDL_CondWait(q->cond, q->mutex);
547 SDL_UnlockMutex(q->mutex);
551 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
552 memset(d, 0, sizeof(Decoder));
555 d->empty_queue_cond = empty_queue_cond;
556 d->start_pts = AV_NOPTS_VALUE;
559 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
565 if (d->queue->abort_request)
568 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
571 if (d->queue->nb_packets == 0)
572 SDL_CondSignal(d->empty_queue_cond);
573 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
575 if (pkt.data == flush_pkt.data) {
576 avcodec_flush_buffers(d->avctx);
578 d->next_pts = d->start_pts;
579 d->next_pts_tb = d->start_pts_tb;
581 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
582 av_packet_unref(&d->pkt);
583 d->pkt_temp = d->pkt = pkt;
584 d->packet_pending = 1;
587 switch (d->avctx->codec_type) {
588 case AVMEDIA_TYPE_VIDEO:
589 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
591 if (decoder_reorder_pts == -1) {
592 frame->pts = av_frame_get_best_effort_timestamp(frame);
593 } else if (!decoder_reorder_pts) {
594 frame->pts = frame->pkt_dts;
598 case AVMEDIA_TYPE_AUDIO:
599 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
601 AVRational tb = (AVRational){1, frame->sample_rate};
602 if (frame->pts != AV_NOPTS_VALUE)
603 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
604 else if (d->next_pts != AV_NOPTS_VALUE)
605 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
606 if (frame->pts != AV_NOPTS_VALUE) {
607 d->next_pts = frame->pts + frame->nb_samples;
612 case AVMEDIA_TYPE_SUBTITLE:
613 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
618 d->packet_pending = 0;
621 d->pkt_temp.pts = AV_NOPTS_VALUE;
622 if (d->pkt_temp.data) {
623 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
624 ret = d->pkt_temp.size;
625 d->pkt_temp.data += ret;
626 d->pkt_temp.size -= ret;
627 if (d->pkt_temp.size <= 0)
628 d->packet_pending = 0;
631 d->packet_pending = 0;
632 d->finished = d->pkt_serial;
636 } while (!got_frame && !d->finished);
641 static void decoder_destroy(Decoder *d) {
642 av_packet_unref(&d->pkt);
643 avcodec_free_context(&d->avctx);
646 static void frame_queue_unref_item(Frame *vp)
648 av_frame_unref(vp->frame);
649 avsubtitle_free(&vp->sub);
652 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
655 memset(f, 0, sizeof(FrameQueue));
656 if (!(f->mutex = SDL_CreateMutex())) {
657 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
658 return AVERROR(ENOMEM);
660 if (!(f->cond = SDL_CreateCond())) {
661 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
662 return AVERROR(ENOMEM);
665 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
666 f->keep_last = !!keep_last;
667 for (i = 0; i < f->max_size; i++)
668 if (!(f->queue[i].frame = av_frame_alloc()))
669 return AVERROR(ENOMEM);
673 static void frame_queue_destory(FrameQueue *f)
676 for (i = 0; i < f->max_size; i++) {
677 Frame *vp = &f->queue[i];
678 frame_queue_unref_item(vp);
679 av_frame_free(&vp->frame);
682 SDL_DestroyMutex(f->mutex);
683 SDL_DestroyCond(f->cond);
686 static void frame_queue_signal(FrameQueue *f)
688 SDL_LockMutex(f->mutex);
689 SDL_CondSignal(f->cond);
690 SDL_UnlockMutex(f->mutex);
693 static Frame *frame_queue_peek(FrameQueue *f)
695 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
698 static Frame *frame_queue_peek_next(FrameQueue *f)
700 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
703 static Frame *frame_queue_peek_last(FrameQueue *f)
705 return &f->queue[f->rindex];
708 static Frame *frame_queue_peek_writable(FrameQueue *f)
710 /* wait until we have space to put a new frame */
711 SDL_LockMutex(f->mutex);
712 while (f->size >= f->max_size &&
713 !f->pktq->abort_request) {
714 SDL_CondWait(f->cond, f->mutex);
716 SDL_UnlockMutex(f->mutex);
718 if (f->pktq->abort_request)
721 return &f->queue[f->windex];
724 static Frame *frame_queue_peek_readable(FrameQueue *f)
726 /* wait until we have a readable a new frame */
727 SDL_LockMutex(f->mutex);
728 while (f->size - f->rindex_shown <= 0 &&
729 !f->pktq->abort_request) {
730 SDL_CondWait(f->cond, f->mutex);
732 SDL_UnlockMutex(f->mutex);
734 if (f->pktq->abort_request)
737 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
740 static void frame_queue_push(FrameQueue *f)
742 if (++f->windex == f->max_size)
744 SDL_LockMutex(f->mutex);
746 SDL_CondSignal(f->cond);
747 SDL_UnlockMutex(f->mutex);
750 static void frame_queue_next(FrameQueue *f)
752 if (f->keep_last && !f->rindex_shown) {
756 frame_queue_unref_item(&f->queue[f->rindex]);
757 if (++f->rindex == f->max_size)
759 SDL_LockMutex(f->mutex);
761 SDL_CondSignal(f->cond);
762 SDL_UnlockMutex(f->mutex);
765 /* return the number of undisplayed frames in the queue */
766 static int frame_queue_nb_remaining(FrameQueue *f)
768 return f->size - f->rindex_shown;
771 /* return last shown position */
772 static int64_t frame_queue_last_pos(FrameQueue *f)
774 Frame *fp = &f->queue[f->rindex];
775 if (f->rindex_shown && fp->serial == f->pktq->serial)
781 static void decoder_abort(Decoder *d, FrameQueue *fq)
783 packet_queue_abort(d->queue);
784 frame_queue_signal(fq);
785 SDL_WaitThread(d->decoder_tid, NULL);
786 d->decoder_tid = NULL;
787 packet_queue_flush(d->queue);
790 static inline void fill_rectangle(int x, int y, int w, int h)
798 SDL_RenderFillRect(renderer, &rect);
801 static void free_picture(Frame *vp)
804 SDL_DestroyTexture(vp->bmp);
809 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
813 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
816 SDL_DestroyTexture(*texture);
817 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
819 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
822 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
824 memset(pixels, 0, pitch * new_height);
825 SDL_UnlockTexture(*texture);
831 static void calculate_display_rect(SDL_Rect *rect,
832 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
833 int pic_width, int pic_height, AVRational pic_sar)
836 int width, height, x, y;
838 if (pic_sar.num == 0)
841 aspect_ratio = av_q2d(pic_sar);
843 if (aspect_ratio <= 0.0)
845 aspect_ratio *= (float)pic_width / (float)pic_height;
847 /* XXX: we suppose the screen has a 1.0 pixel ratio */
849 width = lrint(height * aspect_ratio) & ~1;
850 if (width > scr_width) {
852 height = lrint(width / aspect_ratio) & ~1;
854 x = (scr_width - width) / 2;
855 y = (scr_height - height) / 2;
856 rect->x = scr_xleft + x;
857 rect->y = scr_ytop + y;
858 rect->w = FFMAX(width, 1);
859 rect->h = FFMAX(height, 1);
862 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
864 switch (frame->format) {
865 case AV_PIX_FMT_YUV420P:
866 if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
867 av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
870 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
871 frame->data[1], frame->linesize[1],
872 frame->data[2], frame->linesize[2]);
874 case AV_PIX_FMT_BGRA:
875 if (frame->linesize[0] < 0) {
876 ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
878 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
882 /* This should only happen if we are not using avfilter... */
883 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
884 frame->width, frame->height, frame->format, frame->width, frame->height,
885 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
886 if (*img_convert_ctx != NULL) {
889 if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) {
890 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
891 0, frame->height, pixels, pitch);
892 SDL_UnlockTexture(tex);
895 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
903 static void video_image_display(VideoState *is)
909 vp = frame_queue_peek_last(&is->pictq);
911 if (is->subtitle_st) {
912 if (frame_queue_nb_remaining(&is->subpq) > 0) {
913 sp = frame_queue_peek(&is->subpq);
915 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
920 if (!sp->width || !sp->height) {
921 sp->width = vp->width;
922 sp->height = vp->height;
924 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
927 for (i = 0; i < sp->sub.num_rects; i++) {
928 AVSubtitleRect *sub_rect = sp->sub.rects[i];
930 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
931 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
932 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
933 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
935 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
936 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
937 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
938 0, NULL, NULL, NULL);
939 if (!is->sub_convert_ctx) {
940 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
943 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
944 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
945 0, sub_rect->h, pixels, pitch);
946 SDL_UnlockTexture(is->sub_texture);
956 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
959 if (upload_texture(vp->bmp, vp->frame, &is->img_convert_ctx) < 0)
962 vp->flip_v = vp->frame->linesize[0] < 0;
965 SDL_RenderCopyEx(renderer, vp->bmp, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
967 #if USE_ONEPASS_SUBTITLE_RENDER
968 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
971 double xratio = (double)rect.w / (double)sp->width;
972 double yratio = (double)rect.h / (double)sp->height;
973 for (i = 0; i < sp->sub.num_rects; i++) {
974 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
975 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
976 .y = rect.y + sub_rect->y * yratio,
977 .w = sub_rect->w * xratio,
978 .h = sub_rect->h * yratio};
979 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
986 static inline int compute_mod(int a, int b)
988 return a < 0 ? a%b + b : a%b;
991 static void video_audio_display(VideoState *s)
993 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
994 int ch, channels, h, h2;
996 int rdft_bits, nb_freq;
998 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1000 nb_freq = 1 << (rdft_bits - 1);
1002 /* compute display index : center on currently output samples */
1003 channels = s->audio_tgt.channels;
1004 nb_display_channels = channels;
1006 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1008 delay = s->audio_write_buf_size;
1011 /* to be more precise, we take into account the time spent since
1012 the last buffer computation */
1013 if (audio_callback_time) {
1014 time_diff = av_gettime_relative() - audio_callback_time;
1015 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1018 delay += 2 * data_used;
1019 if (delay < data_used)
1022 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1023 if (s->show_mode == SHOW_MODE_WAVES) {
1025 for (i = 0; i < 1000; i += channels) {
1026 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1027 int a = s->sample_array[idx];
1028 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1029 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1030 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1032 if (h < score && (b ^ c) < 0) {
1039 s->last_i_start = i_start;
1041 i_start = s->last_i_start;
1044 if (s->show_mode == SHOW_MODE_WAVES) {
1045 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1047 /* total height for one channel */
1048 h = s->height / nb_display_channels;
1049 /* graph height / 2 */
1051 for (ch = 0; ch < nb_display_channels; ch++) {
1053 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1054 for (x = 0; x < s->width; x++) {
1055 y = (s->sample_array[i] * h2) >> 15;
1062 fill_rectangle(s->xleft + x, ys, 1, y);
1064 if (i >= SAMPLE_ARRAY_SIZE)
1065 i -= SAMPLE_ARRAY_SIZE;
1069 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1071 for (ch = 1; ch < nb_display_channels; ch++) {
1072 y = s->ytop + ch * h;
1073 fill_rectangle(s->xleft, y, s->width, 1);
1076 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1079 nb_display_channels= FFMIN(nb_display_channels, 2);
1080 if (rdft_bits != s->rdft_bits) {
1081 av_rdft_end(s->rdft);
1082 av_free(s->rdft_data);
1083 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1084 s->rdft_bits = rdft_bits;
1085 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1087 if (!s->rdft || !s->rdft_data){
1088 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1089 s->show_mode = SHOW_MODE_WAVES;
1092 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1095 for (ch = 0; ch < nb_display_channels; ch++) {
1096 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1098 for (x = 0; x < 2 * nb_freq; x++) {
1099 double w = (x-nb_freq) * (1.0 / nb_freq);
1100 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1102 if (i >= SAMPLE_ARRAY_SIZE)
1103 i -= SAMPLE_ARRAY_SIZE;
1105 av_rdft_calc(s->rdft, data[ch]);
1107 /* Least efficient way to do this, we should of course
1108 * directly access it but it is more than fast enough. */
1109 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1111 pixels += pitch * s->height;
1112 for (y = 0; y < s->height; y++) {
1113 double w = 1 / sqrt(nb_freq);
1114 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]));
1115 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1120 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1122 SDL_UnlockTexture(s->vis_texture);
1124 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1128 if (s->xpos >= s->width)
1133 static void stream_component_close(VideoState *is, int stream_index)
1135 AVFormatContext *ic = is->ic;
1136 AVCodecParameters *codecpar;
1138 if (stream_index < 0 || stream_index >= ic->nb_streams)
1140 codecpar = ic->streams[stream_index]->codecpar;
1142 switch (codecpar->codec_type) {
1143 case AVMEDIA_TYPE_AUDIO:
1144 decoder_abort(&is->auddec, &is->sampq);
1146 decoder_destroy(&is->auddec);
1147 swr_free(&is->swr_ctx);
1148 av_freep(&is->audio_buf1);
1149 is->audio_buf1_size = 0;
1150 is->audio_buf = NULL;
1153 av_rdft_end(is->rdft);
1154 av_freep(&is->rdft_data);
1159 case AVMEDIA_TYPE_VIDEO:
1160 decoder_abort(&is->viddec, &is->pictq);
1161 decoder_destroy(&is->viddec);
1163 case AVMEDIA_TYPE_SUBTITLE:
1164 decoder_abort(&is->subdec, &is->subpq);
1165 decoder_destroy(&is->subdec);
1171 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1172 switch (codecpar->codec_type) {
1173 case AVMEDIA_TYPE_AUDIO:
1174 is->audio_st = NULL;
1175 is->audio_stream = -1;
1177 case AVMEDIA_TYPE_VIDEO:
1178 is->video_st = NULL;
1179 is->video_stream = -1;
1181 case AVMEDIA_TYPE_SUBTITLE:
1182 is->subtitle_st = NULL;
1183 is->subtitle_stream = -1;
1190 static void stream_close(VideoState *is)
1192 /* XXX: use a special url_shutdown call to abort parse cleanly */
1193 is->abort_request = 1;
1194 SDL_WaitThread(is->read_tid, NULL);
1196 /* close each stream */
1197 if (is->audio_stream >= 0)
1198 stream_component_close(is, is->audio_stream);
1199 if (is->video_stream >= 0)
1200 stream_component_close(is, is->video_stream);
1201 if (is->subtitle_stream >= 0)
1202 stream_component_close(is, is->subtitle_stream);
1204 avformat_close_input(&is->ic);
1206 packet_queue_destroy(&is->videoq);
1207 packet_queue_destroy(&is->audioq);
1208 packet_queue_destroy(&is->subtitleq);
1210 /* free all pictures */
1211 frame_queue_destory(&is->pictq);
1212 frame_queue_destory(&is->sampq);
1213 frame_queue_destory(&is->subpq);
1214 SDL_DestroyCond(is->continue_read_thread);
1215 sws_freeContext(is->img_convert_ctx);
1216 sws_freeContext(is->sub_convert_ctx);
1217 av_free(is->filename);
1218 if (is->vis_texture)
1219 SDL_DestroyTexture(is->vis_texture);
1220 if (is->sub_texture)
1221 SDL_DestroyTexture(is->sub_texture);
1225 static void do_exit(VideoState *is)
1231 SDL_DestroyRenderer(renderer);
1233 SDL_DestroyWindow(window);
1234 av_lockmgr_register(NULL);
1237 av_freep(&vfilters_list);
1239 avformat_network_deinit();
1243 av_log(NULL, AV_LOG_QUIET, "%s", "");
1247 static void sigterm_handler(int sig)
1252 static void set_default_window_size(int width, int height, AVRational sar)
1255 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1256 default_width = rect.w;
1257 default_height = rect.h;
1260 static int video_open(VideoState *is, Frame *vp)
1264 if (vp && vp->width)
1265 set_default_window_size(vp->width, vp->height, vp->sar);
1276 int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
1278 window_title = input_filename;
1280 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1281 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1282 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1284 SDL_RendererInfo info;
1285 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1287 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1288 renderer = SDL_CreateRenderer(window, -1, 0);
1291 if (!SDL_GetRendererInfo(renderer, &info))
1292 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1296 SDL_SetWindowSize(window, w, h);
1299 if (!window || !renderer) {
1300 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1310 /* display the current picture, if any */
1311 static void video_display(VideoState *is)
1314 video_open(is, NULL);
1316 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1317 SDL_RenderClear(renderer);
1318 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1319 video_audio_display(is);
1320 else if (is->video_st)
1321 video_image_display(is);
1322 SDL_RenderPresent(renderer);
1325 static double get_clock(Clock *c)
1327 if (*c->queue_serial != c->serial)
1332 double time = av_gettime_relative() / 1000000.0;
1333 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1337 static void set_clock_at(Clock *c, double pts, int serial, double time)
1340 c->last_updated = time;
1341 c->pts_drift = c->pts - time;
1345 static void set_clock(Clock *c, double pts, int serial)
1347 double time = av_gettime_relative() / 1000000.0;
1348 set_clock_at(c, pts, serial, time);
1351 static void set_clock_speed(Clock *c, double speed)
1353 set_clock(c, get_clock(c), c->serial);
1357 static void init_clock(Clock *c, int *queue_serial)
1361 c->queue_serial = queue_serial;
1362 set_clock(c, NAN, -1);
1365 static void sync_clock_to_slave(Clock *c, Clock *slave)
1367 double clock = get_clock(c);
1368 double slave_clock = get_clock(slave);
1369 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1370 set_clock(c, slave_clock, slave->serial);
1373 static int get_master_sync_type(VideoState *is) {
1374 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1376 return AV_SYNC_VIDEO_MASTER;
1378 return AV_SYNC_AUDIO_MASTER;
1379 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1381 return AV_SYNC_AUDIO_MASTER;
1383 return AV_SYNC_EXTERNAL_CLOCK;
1385 return AV_SYNC_EXTERNAL_CLOCK;
1389 /* get the current master clock value */
1390 static double get_master_clock(VideoState *is)
1394 switch (get_master_sync_type(is)) {
1395 case AV_SYNC_VIDEO_MASTER:
1396 val = get_clock(&is->vidclk);
1398 case AV_SYNC_AUDIO_MASTER:
1399 val = get_clock(&is->audclk);
1402 val = get_clock(&is->extclk);
1408 static void check_external_clock_speed(VideoState *is) {
1409 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1410 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1411 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1412 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1413 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1414 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1416 double speed = is->extclk.speed;
1418 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1422 /* seek in the stream */
1423 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1425 if (!is->seek_req) {
1428 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1430 is->seek_flags |= AVSEEK_FLAG_BYTE;
1432 SDL_CondSignal(is->continue_read_thread);
1436 /* pause or resume the video */
1437 static void stream_toggle_pause(VideoState *is)
1440 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1441 if (is->read_pause_return != AVERROR(ENOSYS)) {
1442 is->vidclk.paused = 0;
1444 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1446 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1447 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1450 static void toggle_pause(VideoState *is)
1452 stream_toggle_pause(is);
1456 static void toggle_mute(VideoState *is)
1458 is->muted = !is->muted;
1461 static void update_volume(VideoState *is, int sign, int step)
1463 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1466 static void step_to_next_frame(VideoState *is)
1468 /* if the stream is paused unpause it, then step */
1470 stream_toggle_pause(is);
1474 static double compute_target_delay(double delay, VideoState *is)
1476 double sync_threshold, diff = 0;
1478 /* update delay to follow master synchronisation source */
1479 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1480 /* if video is slave, we try to correct big delays by
1481 duplicating or deleting a frame */
1482 diff = get_clock(&is->vidclk) - get_master_clock(is);
1484 /* skip or repeat frame. We take into account the
1485 delay to compute the threshold. I still don't know
1486 if it is the best guess */
1487 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1488 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1489 if (diff <= -sync_threshold)
1490 delay = FFMAX(0, delay + diff);
1491 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1492 delay = delay + diff;
1493 else if (diff >= sync_threshold)
1498 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1504 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1505 if (vp->serial == nextvp->serial) {
1506 double duration = nextvp->pts - vp->pts;
1507 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1508 return vp->duration;
1516 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1517 /* update current video pts */
1518 set_clock(&is->vidclk, pts, serial);
1519 sync_clock_to_slave(&is->extclk, &is->vidclk);
1522 /* called to display each frame */
1523 static void video_refresh(void *opaque, double *remaining_time)
1525 VideoState *is = opaque;
1530 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1531 check_external_clock_speed(is);
1533 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1534 time = av_gettime_relative() / 1000000.0;
1535 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1537 is->last_vis_time = time;
1539 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1544 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1545 // nothing to do, no picture to display in the queue
1547 double last_duration, duration, delay;
1550 /* dequeue the picture */
1551 lastvp = frame_queue_peek_last(&is->pictq);
1552 vp = frame_queue_peek(&is->pictq);
1554 if (vp->serial != is->videoq.serial) {
1555 frame_queue_next(&is->pictq);
1559 if (lastvp->serial != vp->serial)
1560 is->frame_timer = av_gettime_relative() / 1000000.0;
1565 /* compute nominal last_duration */
1566 last_duration = vp_duration(is, lastvp, vp);
1567 delay = compute_target_delay(last_duration, is);
1569 time= av_gettime_relative()/1000000.0;
1570 if (time < is->frame_timer + delay) {
1571 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1575 is->frame_timer += delay;
1576 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1577 is->frame_timer = time;
1579 SDL_LockMutex(is->pictq.mutex);
1580 if (!isnan(vp->pts))
1581 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1582 SDL_UnlockMutex(is->pictq.mutex);
1584 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1585 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1586 duration = vp_duration(is, vp, nextvp);
1587 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1588 is->frame_drops_late++;
1589 frame_queue_next(&is->pictq);
1594 if (is->subtitle_st) {
1595 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1596 sp = frame_queue_peek(&is->subpq);
1598 if (frame_queue_nb_remaining(&is->subpq) > 1)
1599 sp2 = frame_queue_peek_next(&is->subpq);
1603 if (sp->serial != is->subtitleq.serial
1604 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1605 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1609 for (i = 0; i < sp->sub.num_rects; i++) {
1610 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1614 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1615 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1616 memset(pixels, 0, sub_rect->w << 2);
1617 SDL_UnlockTexture(is->sub_texture);
1621 frame_queue_next(&is->subpq);
1628 frame_queue_next(&is->pictq);
1629 is->force_refresh = 1;
1631 if (is->step && !is->paused)
1632 stream_toggle_pause(is);
1635 /* display picture */
1636 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1639 is->force_refresh = 0;
1641 static int64_t last_time;
1643 int aqsize, vqsize, sqsize;
1646 cur_time = av_gettime_relative();
1647 if (!last_time || (cur_time - last_time) >= 30000) {
1652 aqsize = is->audioq.size;
1654 vqsize = is->videoq.size;
1655 if (is->subtitle_st)
1656 sqsize = is->subtitleq.size;
1658 if (is->audio_st && is->video_st)
1659 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1660 else if (is->video_st)
1661 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1662 else if (is->audio_st)
1663 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1664 av_log(NULL, AV_LOG_INFO,
1665 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1666 get_master_clock(is),
1667 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1669 is->frame_drops_early + is->frame_drops_late,
1673 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1674 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1676 last_time = cur_time;
1681 /* allocate a picture (needs to do that in main thread to avoid
1682 potential locking problems */
1683 static void alloc_picture(VideoState *is)
1688 vp = &is->pictq.queue[is->pictq.windex];
1692 if (vp->format == AV_PIX_FMT_YUV420P)
1693 sdl_format = SDL_PIXELFORMAT_YV12;
1695 sdl_format = SDL_PIXELFORMAT_ARGB8888;
1697 if (realloc_texture(&vp->bmp, sdl_format, vp->width, vp->height, SDL_BLENDMODE_NONE, 0) < 0) {
1698 /* SDL allocates a buffer smaller than requested if the video
1699 * overlay hardware is unable to support the requested size. */
1700 av_log(NULL, AV_LOG_FATAL,
1701 "Error: the video system does not support an image\n"
1702 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1703 "to reduce the image size.\n", vp->width, vp->height );
1707 SDL_LockMutex(is->pictq.mutex);
1709 SDL_CondSignal(is->pictq.cond);
1710 SDL_UnlockMutex(is->pictq.mutex);
1713 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1717 #if defined(DEBUG_SYNC)
1718 printf("frame_type=%c pts=%0.3f\n",
1719 av_get_picture_type_char(src_frame->pict_type), pts);
1722 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1725 vp->sar = src_frame->sample_aspect_ratio;
1728 /* alloc or resize hardware picture buffer */
1729 if (!vp->bmp || !vp->allocated ||
1730 vp->width != src_frame->width ||
1731 vp->height != src_frame->height ||
1732 vp->format != src_frame->format) {
1736 vp->width = src_frame->width;
1737 vp->height = src_frame->height;
1738 vp->format = src_frame->format;
1740 /* the allocation must be done in the main thread to avoid
1741 locking problems. */
1742 event.type = FF_ALLOC_EVENT;
1743 event.user.data1 = is;
1744 SDL_PushEvent(&event);
1746 /* wait until the picture is allocated */
1747 SDL_LockMutex(is->pictq.mutex);
1748 while (!vp->allocated && !is->videoq.abort_request) {
1749 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1751 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1752 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, FF_ALLOC_EVENT, FF_ALLOC_EVENT) != 1) {
1753 while (!vp->allocated && !is->abort_request) {
1754 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1757 SDL_UnlockMutex(is->pictq.mutex);
1759 if (is->videoq.abort_request)
1763 /* if the frame is not skipped, then display it */
1766 vp->duration = duration;
1768 vp->serial = serial;
1770 av_frame_move_ref(vp->frame, src_frame);
1771 frame_queue_push(&is->pictq);
1776 static int get_video_frame(VideoState *is, AVFrame *frame)
1780 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1786 if (frame->pts != AV_NOPTS_VALUE)
1787 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1789 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1791 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1792 if (frame->pts != AV_NOPTS_VALUE) {
1793 double diff = dpts - get_master_clock(is);
1794 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1795 diff - is->frame_last_filter_delay < 0 &&
1796 is->viddec.pkt_serial == is->vidclk.serial &&
1797 is->videoq.nb_packets) {
1798 is->frame_drops_early++;
1799 av_frame_unref(frame);
1810 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1811 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1814 int nb_filters = graph->nb_filters;
1815 AVFilterInOut *outputs = NULL, *inputs = NULL;
1818 outputs = avfilter_inout_alloc();
1819 inputs = avfilter_inout_alloc();
1820 if (!outputs || !inputs) {
1821 ret = AVERROR(ENOMEM);
1825 outputs->name = av_strdup("in");
1826 outputs->filter_ctx = source_ctx;
1827 outputs->pad_idx = 0;
1828 outputs->next = NULL;
1830 inputs->name = av_strdup("out");
1831 inputs->filter_ctx = sink_ctx;
1832 inputs->pad_idx = 0;
1833 inputs->next = NULL;
1835 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1838 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1842 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1843 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1844 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1846 ret = avfilter_graph_config(graph, NULL);
1848 avfilter_inout_free(&outputs);
1849 avfilter_inout_free(&inputs);
1853 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1855 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1856 char sws_flags_str[512] = "";
1857 char buffersrc_args[256];
1859 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1860 AVCodecParameters *codecpar = is->video_st->codecpar;
1861 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1862 AVDictionaryEntry *e = NULL;
1864 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1865 if (!strcmp(e->key, "sws_flags")) {
1866 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1868 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1870 if (strlen(sws_flags_str))
1871 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1873 graph->scale_sws_opts = av_strdup(sws_flags_str);
1875 snprintf(buffersrc_args, sizeof(buffersrc_args),
1876 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1877 frame->width, frame->height, frame->format,
1878 is->video_st->time_base.num, is->video_st->time_base.den,
1879 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1880 if (fr.num && fr.den)
1881 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1883 if ((ret = avfilter_graph_create_filter(&filt_src,
1884 avfilter_get_by_name("buffer"),
1885 "ffplay_buffer", buffersrc_args, NULL,
1889 ret = avfilter_graph_create_filter(&filt_out,
1890 avfilter_get_by_name("buffersink"),
1891 "ffplay_buffersink", NULL, NULL, graph);
1895 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1898 last_filter = filt_out;
1900 /* Note: this macro adds a filter before the lastly added filter, so the
1901 * processing order of the filters is in reverse */
1902 #define INSERT_FILT(name, arg) do { \
1903 AVFilterContext *filt_ctx; \
1905 ret = avfilter_graph_create_filter(&filt_ctx, \
1906 avfilter_get_by_name(name), \
1907 "ffplay_" name, arg, NULL, graph); \
1911 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1915 last_filter = filt_ctx; \
1919 double theta = get_rotation(is->video_st);
1921 if (fabs(theta - 90) < 1.0) {
1922 INSERT_FILT("transpose", "clock");
1923 } else if (fabs(theta - 180) < 1.0) {
1924 INSERT_FILT("hflip", NULL);
1925 INSERT_FILT("vflip", NULL);
1926 } else if (fabs(theta - 270) < 1.0) {
1927 INSERT_FILT("transpose", "cclock");
1928 } else if (fabs(theta) > 1.0) {
1929 char rotate_buf[64];
1930 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1931 INSERT_FILT("rotate", rotate_buf);
1935 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1938 is->in_video_filter = filt_src;
1939 is->out_video_filter = filt_out;
1945 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1947 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1948 int sample_rates[2] = { 0, -1 };
1949 int64_t channel_layouts[2] = { 0, -1 };
1950 int channels[2] = { 0, -1 };
1951 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1952 char aresample_swr_opts[512] = "";
1953 AVDictionaryEntry *e = NULL;
1954 char asrc_args[256];
1957 avfilter_graph_free(&is->agraph);
1958 if (!(is->agraph = avfilter_graph_alloc()))
1959 return AVERROR(ENOMEM);
1961 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1962 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1963 if (strlen(aresample_swr_opts))
1964 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1965 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1967 ret = snprintf(asrc_args, sizeof(asrc_args),
1968 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1969 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1970 is->audio_filter_src.channels,
1971 1, is->audio_filter_src.freq);
1972 if (is->audio_filter_src.channel_layout)
1973 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1974 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1976 ret = avfilter_graph_create_filter(&filt_asrc,
1977 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1978 asrc_args, NULL, is->agraph);
1983 ret = avfilter_graph_create_filter(&filt_asink,
1984 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1985 NULL, NULL, is->agraph);
1989 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1991 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1994 if (force_output_format) {
1995 channel_layouts[0] = is->audio_tgt.channel_layout;
1996 channels [0] = is->audio_tgt.channels;
1997 sample_rates [0] = is->audio_tgt.freq;
1998 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2000 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2002 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2004 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2009 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2012 is->in_audio_filter = filt_asrc;
2013 is->out_audio_filter = filt_asink;
2017 avfilter_graph_free(&is->agraph);
2020 #endif /* CONFIG_AVFILTER */
2022 static int audio_thread(void *arg)
2024 VideoState *is = arg;
2025 AVFrame *frame = av_frame_alloc();
2028 int last_serial = -1;
2029 int64_t dec_channel_layout;
2037 return AVERROR(ENOMEM);
2040 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2044 tb = (AVRational){1, frame->sample_rate};
2047 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2050 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2051 frame->format, av_frame_get_channels(frame)) ||
2052 is->audio_filter_src.channel_layout != dec_channel_layout ||
2053 is->audio_filter_src.freq != frame->sample_rate ||
2054 is->auddec.pkt_serial != last_serial;
2057 char buf1[1024], buf2[1024];
2058 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2059 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2060 av_log(NULL, AV_LOG_DEBUG,
2061 "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",
2062 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2063 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2065 is->audio_filter_src.fmt = frame->format;
2066 is->audio_filter_src.channels = av_frame_get_channels(frame);
2067 is->audio_filter_src.channel_layout = dec_channel_layout;
2068 is->audio_filter_src.freq = frame->sample_rate;
2069 last_serial = is->auddec.pkt_serial;
2071 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2075 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2078 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2079 tb = av_buffersink_get_time_base(is->out_audio_filter);
2081 if (!(af = frame_queue_peek_writable(&is->sampq)))
2084 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2085 af->pos = av_frame_get_pkt_pos(frame);
2086 af->serial = is->auddec.pkt_serial;
2087 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2089 av_frame_move_ref(af->frame, frame);
2090 frame_queue_push(&is->sampq);
2093 if (is->audioq.serial != is->auddec.pkt_serial)
2096 if (ret == AVERROR_EOF)
2097 is->auddec.finished = is->auddec.pkt_serial;
2100 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2103 avfilter_graph_free(&is->agraph);
2105 av_frame_free(&frame);
2109 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2111 packet_queue_start(d->queue);
2112 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2113 if (!d->decoder_tid) {
2114 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2115 return AVERROR(ENOMEM);
2120 static int video_thread(void *arg)
2122 VideoState *is = arg;
2123 AVFrame *frame = av_frame_alloc();
2127 AVRational tb = is->video_st->time_base;
2128 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2131 AVFilterGraph *graph = avfilter_graph_alloc();
2132 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2135 enum AVPixelFormat last_format = -2;
2136 int last_serial = -1;
2137 int last_vfilter_idx = 0;
2139 av_frame_free(&frame);
2140 return AVERROR(ENOMEM);
2147 avfilter_graph_free(&graph);
2149 return AVERROR(ENOMEM);
2153 ret = get_video_frame(is, frame);
2160 if ( last_w != frame->width
2161 || last_h != frame->height
2162 || last_format != frame->format
2163 || last_serial != is->viddec.pkt_serial
2164 || last_vfilter_idx != is->vfilter_idx) {
2165 av_log(NULL, AV_LOG_DEBUG,
2166 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2168 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2169 frame->width, frame->height,
2170 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2171 avfilter_graph_free(&graph);
2172 graph = avfilter_graph_alloc();
2173 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2175 event.type = FF_QUIT_EVENT;
2176 event.user.data1 = is;
2177 SDL_PushEvent(&event);
2180 filt_in = is->in_video_filter;
2181 filt_out = is->out_video_filter;
2182 last_w = frame->width;
2183 last_h = frame->height;
2184 last_format = frame->format;
2185 last_serial = is->viddec.pkt_serial;
2186 last_vfilter_idx = is->vfilter_idx;
2187 frame_rate = av_buffersink_get_frame_rate(filt_out);
2190 ret = av_buffersrc_add_frame(filt_in, frame);
2195 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2197 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2199 if (ret == AVERROR_EOF)
2200 is->viddec.finished = is->viddec.pkt_serial;
2205 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2206 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2207 is->frame_last_filter_delay = 0;
2208 tb = av_buffersink_get_time_base(filt_out);
2210 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2211 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2212 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2213 av_frame_unref(frame);
2223 avfilter_graph_free(&graph);
2225 av_frame_free(&frame);
2229 static int subtitle_thread(void *arg)
2231 VideoState *is = arg;
2237 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2240 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2245 if (got_subtitle && sp->sub.format == 0) {
2246 if (sp->sub.pts != AV_NOPTS_VALUE)
2247 pts = sp->sub.pts / (double)AV_TIME_BASE;
2249 sp->serial = is->subdec.pkt_serial;
2250 sp->width = is->subdec.avctx->width;
2251 sp->height = is->subdec.avctx->height;
2254 /* now we can update the picture count */
2255 frame_queue_push(&is->subpq);
2256 } else if (got_subtitle) {
2257 avsubtitle_free(&sp->sub);
2263 /* copy samples for viewing in editor window */
2264 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2268 size = samples_size / sizeof(short);
2270 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2273 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2275 is->sample_array_index += len;
2276 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2277 is->sample_array_index = 0;
2282 /* return the wanted number of samples to get better sync if sync_type is video
2283 * or external master clock */
2284 static int synchronize_audio(VideoState *is, int nb_samples)
2286 int wanted_nb_samples = nb_samples;
2288 /* if not master, then we try to remove or add samples to correct the clock */
2289 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2290 double diff, avg_diff;
2291 int min_nb_samples, max_nb_samples;
2293 diff = get_clock(&is->audclk) - get_master_clock(is);
2295 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2296 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2297 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2298 /* not enough measures to have a correct estimate */
2299 is->audio_diff_avg_count++;
2301 /* estimate the A-V difference */
2302 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2304 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2305 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2306 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2307 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2308 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2310 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2311 diff, avg_diff, wanted_nb_samples - nb_samples,
2312 is->audio_clock, is->audio_diff_threshold);
2315 /* too big difference : may be initial PTS errors, so
2317 is->audio_diff_avg_count = 0;
2318 is->audio_diff_cum = 0;
2322 return wanted_nb_samples;
2326 * Decode one audio frame and return its uncompressed size.
2328 * The processed audio frame is decoded, converted if required, and
2329 * stored in is->audio_buf, with size in bytes given by the return
2332 static int audio_decode_frame(VideoState *is)
2334 int data_size, resampled_data_size;
2335 int64_t dec_channel_layout;
2336 av_unused double audio_clock0;
2337 int wanted_nb_samples;
2345 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2346 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2351 if (!(af = frame_queue_peek_readable(&is->sampq)))
2353 frame_queue_next(&is->sampq);
2354 } while (af->serial != is->audioq.serial);
2356 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2357 af->frame->nb_samples,
2358 af->frame->format, 1);
2360 dec_channel_layout =
2361 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2362 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2363 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2365 if (af->frame->format != is->audio_src.fmt ||
2366 dec_channel_layout != is->audio_src.channel_layout ||
2367 af->frame->sample_rate != is->audio_src.freq ||
2368 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2369 swr_free(&is->swr_ctx);
2370 is->swr_ctx = swr_alloc_set_opts(NULL,
2371 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2372 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2374 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2375 av_log(NULL, AV_LOG_ERROR,
2376 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2377 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2378 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2379 swr_free(&is->swr_ctx);
2382 is->audio_src.channel_layout = dec_channel_layout;
2383 is->audio_src.channels = av_frame_get_channels(af->frame);
2384 is->audio_src.freq = af->frame->sample_rate;
2385 is->audio_src.fmt = af->frame->format;
2389 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2390 uint8_t **out = &is->audio_buf1;
2391 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2392 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2395 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2398 if (wanted_nb_samples != af->frame->nb_samples) {
2399 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2400 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2401 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2405 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2406 if (!is->audio_buf1)
2407 return AVERROR(ENOMEM);
2408 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2410 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2413 if (len2 == out_count) {
2414 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2415 if (swr_init(is->swr_ctx) < 0)
2416 swr_free(&is->swr_ctx);
2418 is->audio_buf = is->audio_buf1;
2419 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2421 is->audio_buf = af->frame->data[0];
2422 resampled_data_size = data_size;
2425 audio_clock0 = is->audio_clock;
2426 /* update the audio clock with the pts */
2427 if (!isnan(af->pts))
2428 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2430 is->audio_clock = NAN;
2431 is->audio_clock_serial = af->serial;
2434 static double last_clock;
2435 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2436 is->audio_clock - last_clock,
2437 is->audio_clock, audio_clock0);
2438 last_clock = is->audio_clock;
2441 return resampled_data_size;
2444 /* prepare a new audio buffer */
2445 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2447 VideoState *is = opaque;
2448 int audio_size, len1;
2450 audio_callback_time = av_gettime_relative();
2453 if (is->audio_buf_index >= is->audio_buf_size) {
2454 audio_size = audio_decode_frame(is);
2455 if (audio_size < 0) {
2456 /* if error, just output silence */
2457 is->audio_buf = NULL;
2458 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2460 if (is->show_mode != SHOW_MODE_VIDEO)
2461 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2462 is->audio_buf_size = audio_size;
2464 is->audio_buf_index = 0;
2466 len1 = is->audio_buf_size - is->audio_buf_index;
2469 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2470 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2472 memset(stream, 0, len1);
2473 if (!is->muted && is->audio_buf)
2474 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2478 is->audio_buf_index += len1;
2480 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2481 /* Let's assume the audio driver that is used by SDL has two periods. */
2482 if (!isnan(is->audio_clock)) {
2483 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);
2484 sync_clock_to_slave(&is->extclk, &is->audclk);
2488 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2490 SDL_AudioSpec wanted_spec, spec;
2492 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2493 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2494 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2496 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2498 wanted_nb_channels = atoi(env);
2499 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2501 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2502 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2503 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2505 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2506 wanted_spec.channels = wanted_nb_channels;
2507 wanted_spec.freq = wanted_sample_rate;
2508 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2509 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2512 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2513 next_sample_rate_idx--;
2514 wanted_spec.format = AUDIO_S16SYS;
2515 wanted_spec.silence = 0;
2516 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2517 wanted_spec.callback = sdl_audio_callback;
2518 wanted_spec.userdata = opaque;
2519 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2520 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2521 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2522 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2523 if (!wanted_spec.channels) {
2524 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2525 wanted_spec.channels = wanted_nb_channels;
2526 if (!wanted_spec.freq) {
2527 av_log(NULL, AV_LOG_ERROR,
2528 "No more combinations to try, audio open failed\n");
2532 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2534 if (spec.format != AUDIO_S16SYS) {
2535 av_log(NULL, AV_LOG_ERROR,
2536 "SDL advised audio format %d is not supported!\n", spec.format);
2539 if (spec.channels != wanted_spec.channels) {
2540 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2541 if (!wanted_channel_layout) {
2542 av_log(NULL, AV_LOG_ERROR,
2543 "SDL advised channel count %d is not supported!\n", spec.channels);
2548 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2549 audio_hw_params->freq = spec.freq;
2550 audio_hw_params->channel_layout = wanted_channel_layout;
2551 audio_hw_params->channels = spec.channels;
2552 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2553 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);
2554 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2555 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2561 /* open a given stream. Return 0 if OK */
2562 static int stream_component_open(VideoState *is, int stream_index)
2564 AVFormatContext *ic = is->ic;
2565 AVCodecContext *avctx;
2567 const char *forced_codec_name = NULL;
2568 AVDictionary *opts = NULL;
2569 AVDictionaryEntry *t = NULL;
2570 int sample_rate, nb_channels;
2571 int64_t channel_layout;
2573 int stream_lowres = lowres;
2575 if (stream_index < 0 || stream_index >= ic->nb_streams)
2578 avctx = avcodec_alloc_context3(NULL);
2580 return AVERROR(ENOMEM);
2582 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2585 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2587 codec = avcodec_find_decoder(avctx->codec_id);
2589 switch(avctx->codec_type){
2590 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2591 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2592 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2594 if (forced_codec_name)
2595 codec = avcodec_find_decoder_by_name(forced_codec_name);
2597 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2598 "No codec could be found with name '%s'\n", forced_codec_name);
2599 else av_log(NULL, AV_LOG_WARNING,
2600 "No codec could be found with id %d\n", avctx->codec_id);
2601 ret = AVERROR(EINVAL);
2605 avctx->codec_id = codec->id;
2606 if(stream_lowres > av_codec_get_max_lowres(codec)){
2607 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2608 av_codec_get_max_lowres(codec));
2609 stream_lowres = av_codec_get_max_lowres(codec);
2611 av_codec_set_lowres(avctx, stream_lowres);
2614 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2617 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2619 if(codec->capabilities & AV_CODEC_CAP_DR1)
2620 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2623 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2624 if (!av_dict_get(opts, "threads", NULL, 0))
2625 av_dict_set(&opts, "threads", "auto", 0);
2627 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2628 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2629 av_dict_set(&opts, "refcounted_frames", "1", 0);
2630 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2633 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2634 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2635 ret = AVERROR_OPTION_NOT_FOUND;
2640 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2641 switch (avctx->codec_type) {
2642 case AVMEDIA_TYPE_AUDIO:
2645 AVFilterContext *sink;
2647 is->audio_filter_src.freq = avctx->sample_rate;
2648 is->audio_filter_src.channels = avctx->channels;
2649 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2650 is->audio_filter_src.fmt = avctx->sample_fmt;
2651 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2653 sink = is->out_audio_filter;
2654 sample_rate = av_buffersink_get_sample_rate(sink);
2655 nb_channels = av_buffersink_get_channels(sink);
2656 channel_layout = av_buffersink_get_channel_layout(sink);
2659 sample_rate = avctx->sample_rate;
2660 nb_channels = avctx->channels;
2661 channel_layout = avctx->channel_layout;
2664 /* prepare audio output */
2665 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2667 is->audio_hw_buf_size = ret;
2668 is->audio_src = is->audio_tgt;
2669 is->audio_buf_size = 0;
2670 is->audio_buf_index = 0;
2672 /* init averaging filter */
2673 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2674 is->audio_diff_avg_count = 0;
2675 /* since we do not have a precise anough audio FIFO fullness,
2676 we correct audio sync only if larger than this threshold */
2677 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2679 is->audio_stream = stream_index;
2680 is->audio_st = ic->streams[stream_index];
2682 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2683 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2684 is->auddec.start_pts = is->audio_st->start_time;
2685 is->auddec.start_pts_tb = is->audio_st->time_base;
2687 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2691 case AVMEDIA_TYPE_VIDEO:
2692 is->video_stream = stream_index;
2693 is->video_st = ic->streams[stream_index];
2695 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2696 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2698 is->queue_attachments_req = 1;
2700 case AVMEDIA_TYPE_SUBTITLE:
2701 is->subtitle_stream = stream_index;
2702 is->subtitle_st = ic->streams[stream_index];
2704 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2705 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2714 avcodec_free_context(&avctx);
2716 av_dict_free(&opts);
2721 static int decode_interrupt_cb(void *ctx)
2723 VideoState *is = ctx;
2724 return is->abort_request;
2727 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2728 return stream_id < 0 ||
2729 queue->abort_request ||
2730 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2731 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2734 static int is_realtime(AVFormatContext *s)
2736 if( !strcmp(s->iformat->name, "rtp")
2737 || !strcmp(s->iformat->name, "rtsp")
2738 || !strcmp(s->iformat->name, "sdp")
2742 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2743 || !strncmp(s->filename, "udp:", 4)
2750 /* this thread gets the stream from the disk or the network */
2751 static int read_thread(void *arg)
2753 VideoState *is = arg;
2754 AVFormatContext *ic = NULL;
2756 int st_index[AVMEDIA_TYPE_NB];
2757 AVPacket pkt1, *pkt = &pkt1;
2758 int64_t stream_start_time;
2759 int pkt_in_play_range = 0;
2760 AVDictionaryEntry *t;
2761 AVDictionary **opts;
2762 int orig_nb_streams;
2763 SDL_mutex *wait_mutex = SDL_CreateMutex();
2764 int scan_all_pmts_set = 0;
2768 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2769 ret = AVERROR(ENOMEM);
2773 memset(st_index, -1, sizeof(st_index));
2774 is->last_video_stream = is->video_stream = -1;
2775 is->last_audio_stream = is->audio_stream = -1;
2776 is->last_subtitle_stream = is->subtitle_stream = -1;
2779 ic = avformat_alloc_context();
2781 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2782 ret = AVERROR(ENOMEM);
2785 ic->interrupt_callback.callback = decode_interrupt_cb;
2786 ic->interrupt_callback.opaque = is;
2787 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2788 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2789 scan_all_pmts_set = 1;
2791 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2793 print_error(is->filename, err);
2797 if (scan_all_pmts_set)
2798 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2800 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2801 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2802 ret = AVERROR_OPTION_NOT_FOUND;
2808 ic->flags |= AVFMT_FLAG_GENPTS;
2810 av_format_inject_global_side_data(ic);
2812 opts = setup_find_stream_info_opts(ic, codec_opts);
2813 orig_nb_streams = ic->nb_streams;
2815 err = avformat_find_stream_info(ic, opts);
2817 for (i = 0; i < orig_nb_streams; i++)
2818 av_dict_free(&opts[i]);
2822 av_log(NULL, AV_LOG_WARNING,
2823 "%s: could not find codec parameters\n", is->filename);
2829 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2831 if (seek_by_bytes < 0)
2832 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2834 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2836 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2837 window_title = av_asprintf("%s - %s", t->value, input_filename);
2839 /* if seeking requested, we execute it */
2840 if (start_time != AV_NOPTS_VALUE) {
2843 timestamp = start_time;
2844 /* add the stream start time */
2845 if (ic->start_time != AV_NOPTS_VALUE)
2846 timestamp += ic->start_time;
2847 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2849 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2850 is->filename, (double)timestamp / AV_TIME_BASE);
2854 is->realtime = is_realtime(ic);
2857 av_dump_format(ic, 0, is->filename, 0);
2859 for (i = 0; i < ic->nb_streams; i++) {
2860 AVStream *st = ic->streams[i];
2861 enum AVMediaType type = st->codecpar->codec_type;
2862 st->discard = AVDISCARD_ALL;
2863 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2864 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2867 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2868 if (wanted_stream_spec[i] && st_index[i] == -1) {
2869 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));
2870 st_index[i] = INT_MAX;
2875 st_index[AVMEDIA_TYPE_VIDEO] =
2876 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2877 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2879 st_index[AVMEDIA_TYPE_AUDIO] =
2880 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2881 st_index[AVMEDIA_TYPE_AUDIO],
2882 st_index[AVMEDIA_TYPE_VIDEO],
2884 if (!video_disable && !subtitle_disable)
2885 st_index[AVMEDIA_TYPE_SUBTITLE] =
2886 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2887 st_index[AVMEDIA_TYPE_SUBTITLE],
2888 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2889 st_index[AVMEDIA_TYPE_AUDIO] :
2890 st_index[AVMEDIA_TYPE_VIDEO]),
2893 is->show_mode = show_mode;
2894 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2895 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2896 AVCodecParameters *codecpar = st->codecpar;
2897 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2898 if (codecpar->width)
2899 set_default_window_size(codecpar->width, codecpar->height, sar);
2902 /* open the streams */
2903 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2904 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2908 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2909 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2911 if (is->show_mode == SHOW_MODE_NONE)
2912 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2914 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2915 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2918 if (is->video_stream < 0 && is->audio_stream < 0) {
2919 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2925 if (infinite_buffer < 0 && is->realtime)
2926 infinite_buffer = 1;
2929 if (is->abort_request)
2931 if (is->paused != is->last_paused) {
2932 is->last_paused = is->paused;
2934 is->read_pause_return = av_read_pause(ic);
2938 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2940 (!strcmp(ic->iformat->name, "rtsp") ||
2941 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2942 /* wait 10 ms to avoid trying to get another packet */
2949 int64_t seek_target = is->seek_pos;
2950 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2951 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2952 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2953 // of the seek_pos/seek_rel variables
2955 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2957 av_log(NULL, AV_LOG_ERROR,
2958 "%s: error while seeking\n", is->ic->filename);
2960 if (is->audio_stream >= 0) {
2961 packet_queue_flush(&is->audioq);
2962 packet_queue_put(&is->audioq, &flush_pkt);
2964 if (is->subtitle_stream >= 0) {
2965 packet_queue_flush(&is->subtitleq);
2966 packet_queue_put(&is->subtitleq, &flush_pkt);
2968 if (is->video_stream >= 0) {
2969 packet_queue_flush(&is->videoq);
2970 packet_queue_put(&is->videoq, &flush_pkt);
2972 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2973 set_clock(&is->extclk, NAN, 0);
2975 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2979 is->queue_attachments_req = 1;
2982 step_to_next_frame(is);
2984 if (is->queue_attachments_req) {
2985 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2987 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2989 packet_queue_put(&is->videoq, ©);
2990 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2992 is->queue_attachments_req = 0;
2995 /* if the queue are full, no need to read more */
2996 if (infinite_buffer<1 &&
2997 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2998 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2999 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
3000 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
3002 SDL_LockMutex(wait_mutex);
3003 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3004 SDL_UnlockMutex(wait_mutex);
3008 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3009 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3010 if (loop != 1 && (!loop || --loop)) {
3011 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3012 } else if (autoexit) {
3017 ret = av_read_frame(ic, pkt);
3019 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3020 if (is->video_stream >= 0)
3021 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3022 if (is->audio_stream >= 0)
3023 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3024 if (is->subtitle_stream >= 0)
3025 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3028 if (ic->pb && ic->pb->error)
3030 SDL_LockMutex(wait_mutex);
3031 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3032 SDL_UnlockMutex(wait_mutex);
3037 /* check if packet is in play range specified by user, then queue, otherwise discard */
3038 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3039 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3040 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3041 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3042 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3043 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3044 <= ((double)duration / 1000000);
3045 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3046 packet_queue_put(&is->audioq, pkt);
3047 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3048 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3049 packet_queue_put(&is->videoq, pkt);
3050 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3051 packet_queue_put(&is->subtitleq, pkt);
3053 av_packet_unref(pkt);
3060 avformat_close_input(&ic);
3065 event.type = FF_QUIT_EVENT;
3066 event.user.data1 = is;
3067 SDL_PushEvent(&event);
3069 SDL_DestroyMutex(wait_mutex);
3073 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3077 is = av_mallocz(sizeof(VideoState));
3080 is->filename = av_strdup(filename);
3083 is->iformat = iformat;
3087 /* start video display */
3088 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3090 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3092 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3095 if (packet_queue_init(&is->videoq) < 0 ||
3096 packet_queue_init(&is->audioq) < 0 ||
3097 packet_queue_init(&is->subtitleq) < 0)
3100 if (!(is->continue_read_thread = SDL_CreateCond())) {
3101 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3105 init_clock(&is->vidclk, &is->videoq.serial);
3106 init_clock(&is->audclk, &is->audioq.serial);
3107 init_clock(&is->extclk, &is->extclk.serial);
3108 is->audio_clock_serial = -1;
3109 if (startup_volume < 0)
3110 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3111 if (startup_volume > 100)
3112 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3113 startup_volume = av_clip(startup_volume, 0, 100);
3114 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3115 is->audio_volume = startup_volume;
3117 is->av_sync_type = av_sync_type;
3118 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3119 if (!is->read_tid) {
3120 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3128 static void stream_cycle_channel(VideoState *is, int codec_type)
3130 AVFormatContext *ic = is->ic;
3131 int start_index, stream_index;
3134 AVProgram *p = NULL;
3135 int nb_streams = is->ic->nb_streams;
3137 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3138 start_index = is->last_video_stream;
3139 old_index = is->video_stream;
3140 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3141 start_index = is->last_audio_stream;
3142 old_index = is->audio_stream;
3144 start_index = is->last_subtitle_stream;
3145 old_index = is->subtitle_stream;
3147 stream_index = start_index;
3149 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3150 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3152 nb_streams = p->nb_stream_indexes;
3153 for (start_index = 0; start_index < nb_streams; start_index++)
3154 if (p->stream_index[start_index] == stream_index)
3156 if (start_index == nb_streams)
3158 stream_index = start_index;
3163 if (++stream_index >= nb_streams)
3165 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3168 is->last_subtitle_stream = -1;
3171 if (start_index == -1)
3175 if (stream_index == start_index)
3177 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3178 if (st->codecpar->codec_type == codec_type) {
3179 /* check that parameters are OK */
3180 switch (codec_type) {
3181 case AVMEDIA_TYPE_AUDIO:
3182 if (st->codecpar->sample_rate != 0 &&
3183 st->codecpar->channels != 0)
3186 case AVMEDIA_TYPE_VIDEO:
3187 case AVMEDIA_TYPE_SUBTITLE:
3195 if (p && stream_index != -1)
3196 stream_index = p->stream_index[stream_index];
3197 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3198 av_get_media_type_string(codec_type),
3202 stream_component_close(is, old_index);
3203 stream_component_open(is, stream_index);
3207 static void toggle_full_screen(VideoState *is)
3209 is_full_screen = !is_full_screen;
3210 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3213 static void toggle_audio_display(VideoState *is)
3215 int next = is->show_mode;
3217 next = (next + 1) % SHOW_MODE_NB;
3218 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3219 if (is->show_mode != next) {
3220 is->force_refresh = 1;
3221 is->show_mode = next;
3225 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3226 double remaining_time = 0.0;
3228 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3229 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3233 if (remaining_time > 0.0)
3234 av_usleep((int64_t)(remaining_time * 1000000.0));
3235 remaining_time = REFRESH_RATE;
3236 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3237 video_refresh(is, &remaining_time);
3242 static void seek_chapter(VideoState *is, int incr)
3244 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3247 if (!is->ic->nb_chapters)
3250 /* find the current chapter */
3251 for (i = 0; i < is->ic->nb_chapters; i++) {
3252 AVChapter *ch = is->ic->chapters[i];
3253 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3261 if (i >= is->ic->nb_chapters)
3264 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3265 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3266 AV_TIME_BASE_Q), 0, 0);
3269 /* handle an event sent by the GUI */
3270 static void event_loop(VideoState *cur_stream)
3273 double incr, pos, frac;
3277 refresh_loop_wait_event(cur_stream, &event);
3278 switch (event.type) {
3280 if (exit_on_keydown) {
3281 do_exit(cur_stream);
3284 switch (event.key.keysym.sym) {
3287 do_exit(cur_stream);
3290 toggle_full_screen(cur_stream);
3291 cur_stream->force_refresh = 1;
3295 toggle_pause(cur_stream);
3298 toggle_mute(cur_stream);
3300 case SDLK_KP_MULTIPLY:
3302 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3304 case SDLK_KP_DIVIDE:
3306 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3308 case SDLK_s: // S: Step to next frame
3309 step_to_next_frame(cur_stream);
3312 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3315 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3318 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3319 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3320 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3323 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3327 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3328 if (++cur_stream->vfilter_idx >= nb_vfilters)
3329 cur_stream->vfilter_idx = 0;
3331 cur_stream->vfilter_idx = 0;
3332 toggle_audio_display(cur_stream);
3335 toggle_audio_display(cur_stream);
3339 if (cur_stream->ic->nb_chapters <= 1) {
3343 seek_chapter(cur_stream, 1);
3346 if (cur_stream->ic->nb_chapters <= 1) {
3350 seek_chapter(cur_stream, -1);
3364 if (seek_by_bytes) {
3366 if (pos < 0 && cur_stream->video_stream >= 0)
3367 pos = frame_queue_last_pos(&cur_stream->pictq);
3368 if (pos < 0 && cur_stream->audio_stream >= 0)
3369 pos = frame_queue_last_pos(&cur_stream->sampq);
3371 pos = avio_tell(cur_stream->ic->pb);
3372 if (cur_stream->ic->bit_rate)
3373 incr *= cur_stream->ic->bit_rate / 8.0;
3377 stream_seek(cur_stream, pos, incr, 1);
3379 pos = get_master_clock(cur_stream);
3381 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3383 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3384 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3385 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3392 case SDL_MOUSEBUTTONDOWN:
3393 if (exit_on_mousedown) {
3394 do_exit(cur_stream);
3397 if (event.button.button == SDL_BUTTON_LEFT) {
3398 static int64_t last_mouse_left_click = 0;
3399 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3400 toggle_full_screen(cur_stream);
3401 cur_stream->force_refresh = 1;
3402 last_mouse_left_click = 0;
3404 last_mouse_left_click = av_gettime_relative();
3407 case SDL_MOUSEMOTION:
3408 if (cursor_hidden) {
3412 cursor_last_shown = av_gettime_relative();
3413 if (event.type == SDL_MOUSEBUTTONDOWN) {
3414 if (event.button.button != SDL_BUTTON_RIGHT)
3418 if (!(event.motion.state & SDL_BUTTON_RMASK))
3422 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3423 uint64_t size = avio_size(cur_stream->ic->pb);
3424 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3428 int tns, thh, tmm, tss;
3429 tns = cur_stream->ic->duration / 1000000LL;
3431 tmm = (tns % 3600) / 60;
3433 frac = x / cur_stream->width;
3436 mm = (ns % 3600) / 60;
3438 av_log(NULL, AV_LOG_INFO,
3439 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3440 hh, mm, ss, thh, tmm, tss);
3441 ts = frac * cur_stream->ic->duration;
3442 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3443 ts += cur_stream->ic->start_time;
3444 stream_seek(cur_stream, ts, 0, 0);
3447 case SDL_WINDOWEVENT:
3448 switch (event.window.event) {
3449 case SDL_WINDOWEVENT_RESIZED:
3450 screen_width = cur_stream->width = event.window.data1;
3451 screen_height = cur_stream->height = event.window.data2;
3452 if (cur_stream->vis_texture) {
3453 SDL_DestroyTexture(cur_stream->vis_texture);
3454 cur_stream->vis_texture = NULL;
3456 case SDL_WINDOWEVENT_EXPOSED:
3457 cur_stream->force_refresh = 1;
3462 do_exit(cur_stream);
3464 case FF_ALLOC_EVENT:
3465 alloc_picture(event.user.data1);
3473 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3475 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3476 return opt_default(NULL, "video_size", arg);
3479 static int opt_width(void *optctx, const char *opt, const char *arg)
3481 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3485 static int opt_height(void *optctx, const char *opt, const char *arg)
3487 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3491 static int opt_format(void *optctx, const char *opt, const char *arg)
3493 file_iformat = av_find_input_format(arg);
3494 if (!file_iformat) {
3495 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3496 return AVERROR(EINVAL);
3501 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3503 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3504 return opt_default(NULL, "pixel_format", arg);
3507 static int opt_sync(void *optctx, const char *opt, const char *arg)
3509 if (!strcmp(arg, "audio"))
3510 av_sync_type = AV_SYNC_AUDIO_MASTER;
3511 else if (!strcmp(arg, "video"))
3512 av_sync_type = AV_SYNC_VIDEO_MASTER;
3513 else if (!strcmp(arg, "ext"))
3514 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3516 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3522 static int opt_seek(void *optctx, const char *opt, const char *arg)
3524 start_time = parse_time_or_die(opt, arg, 1);
3528 static int opt_duration(void *optctx, const char *opt, const char *arg)
3530 duration = parse_time_or_die(opt, arg, 1);
3534 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3536 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3537 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3538 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3539 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3543 static void opt_input_file(void *optctx, const char *filename)
3545 if (input_filename) {
3546 av_log(NULL, AV_LOG_FATAL,
3547 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3548 filename, input_filename);
3551 if (!strcmp(filename, "-"))
3553 input_filename = filename;
3556 static int opt_codec(void *optctx, const char *opt, const char *arg)
3558 const char *spec = strchr(opt, ':');
3560 av_log(NULL, AV_LOG_ERROR,
3561 "No media specifier was specified in '%s' in option '%s'\n",
3563 return AVERROR(EINVAL);
3567 case 'a' : audio_codec_name = arg; break;
3568 case 's' : subtitle_codec_name = arg; break;
3569 case 'v' : video_codec_name = arg; break;
3571 av_log(NULL, AV_LOG_ERROR,
3572 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3573 return AVERROR(EINVAL);
3580 static const OptionDef options[] = {
3581 #include "cmdutils_common_opts.h"
3582 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3583 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3584 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3585 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3586 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3587 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3588 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3589 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3590 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3591 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3592 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3593 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3594 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3595 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3596 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3597 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3598 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3599 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3600 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3601 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3602 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3603 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3604 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3605 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3606 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3607 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3608 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3609 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3610 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3611 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3613 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3614 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3616 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3617 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3618 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3619 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3620 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3621 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3622 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3623 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3624 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3628 static void show_usage(void)
3630 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3631 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3632 av_log(NULL, AV_LOG_INFO, "\n");
3635 void show_help_default(const char *opt, const char *arg)
3637 av_log_set_callback(log_callback_help);
3639 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3640 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3642 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3643 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3644 #if !CONFIG_AVFILTER
3645 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3647 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3649 printf("\nWhile playing:\n"
3651 "f toggle full screen\n"
3654 "9, 0 decrease and increase volume respectively\n"
3655 "/, * decrease and increase volume respectively\n"
3656 "a cycle audio channel in the current program\n"
3657 "v cycle video channel\n"
3658 "t cycle subtitle channel in the current program\n"
3660 "w cycle video filters or show modes\n"
3661 "s activate frame-step mode\n"
3662 "left/right seek backward/forward 10 seconds\n"
3663 "down/up seek backward/forward 1 minute\n"
3664 "page down/page up seek backward/forward 10 minutes\n"
3665 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3666 "left double-click toggle full screen\n"
3670 static int lockmgr(void **mtx, enum AVLockOp op)
3673 case AV_LOCK_CREATE:
3674 *mtx = SDL_CreateMutex();
3676 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3680 case AV_LOCK_OBTAIN:
3681 return !!SDL_LockMutex(*mtx);
3682 case AV_LOCK_RELEASE:
3683 return !!SDL_UnlockMutex(*mtx);
3684 case AV_LOCK_DESTROY:
3685 SDL_DestroyMutex(*mtx);
3691 /* Called from the main */
3692 int main(int argc, char **argv)
3699 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3700 parse_loglevel(argc, argv, options);
3702 /* register all codecs, demux and protocols */
3704 avdevice_register_all();
3707 avfilter_register_all();
3710 avformat_network_init();
3714 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3715 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3717 show_banner(argc, argv, options);
3719 parse_options(NULL, argc, argv, options, opt_input_file);
3721 if (!input_filename) {
3723 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3724 av_log(NULL, AV_LOG_FATAL,
3725 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3729 if (display_disable) {
3732 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3734 flags &= ~SDL_INIT_AUDIO;
3736 /* Try to work around an occasional ALSA buffer underflow issue when the
3737 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3738 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3739 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3741 if (display_disable)
3742 flags &= ~SDL_INIT_VIDEO;
3743 if (SDL_Init (flags)) {
3744 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3745 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3749 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3750 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3752 if (av_lockmgr_register(lockmgr)) {
3753 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3757 av_init_packet(&flush_pkt);
3758 flush_pkt.data = (uint8_t *)&flush_pkt;
3760 is = stream_open(input_filename, file_iformat);
3762 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");