2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control in dB */
77 #define SDL_VOLUME_STEP (0.75)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
110 static unsigned sws_flags = SWS_BICUBIC;
112 typedef struct MyAVPacketList {
114 struct MyAVPacketList *next;
118 typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
134 typedef struct AudioParams {
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
143 typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
148 int serial; /* clock is based on a packet with this serial */
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
169 typedef struct FrameQueue {
170 Frame queue[FRAME_QUEUE_SIZE];
183 AV_SYNC_AUDIO_MASTER, /* default choice */
184 AV_SYNC_VIDEO_MASTER,
185 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
188 typedef struct Decoder {
191 AVCodecContext *avctx;
195 SDL_cond *empty_queue_cond;
197 AVRational start_pts_tb;
199 AVRational next_pts_tb;
200 SDL_Thread *decoder_tid;
203 typedef struct VideoState {
204 SDL_Thread *read_tid;
205 AVInputFormat *iformat;
210 int queue_attachments_req;
215 int read_pause_return;
236 int audio_clock_serial;
237 double audio_diff_cum; /* used for AV difference average computation */
238 double audio_diff_avg_coef;
239 double audio_diff_threshold;
240 int audio_diff_avg_count;
243 int audio_hw_buf_size;
246 unsigned int audio_buf_size; /* in bytes */
247 unsigned int audio_buf1_size;
248 int audio_buf_index; /* in bytes */
249 int audio_write_buf_size;
252 struct AudioParams audio_src;
254 struct AudioParams audio_filter_src;
256 struct AudioParams audio_tgt;
257 struct SwrContext *swr_ctx;
258 int frame_drops_early;
259 int frame_drops_late;
262 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
264 int16_t sample_array[SAMPLE_ARRAY_SIZE];
265 int sample_array_index;
269 FFTSample *rdft_data;
271 double last_vis_time;
272 SDL_Texture *vis_texture;
273 SDL_Texture *sub_texture;
274 SDL_Texture *vid_texture;
277 AVStream *subtitle_st;
278 PacketQueue subtitleq;
281 double frame_last_returned_time;
282 double frame_last_filter_delay;
286 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
287 struct SwsContext *img_convert_ctx;
288 struct SwsContext *sub_convert_ctx;
292 int width, height, xleft, ytop;
297 AVFilterContext *in_video_filter; // the first filter in the video chain
298 AVFilterContext *out_video_filter; // the last filter in the video chain
299 AVFilterContext *in_audio_filter; // the first filter in the audio chain
300 AVFilterContext *out_audio_filter; // the last filter in the audio chain
301 AVFilterGraph *agraph; // audio filter graph
304 int last_video_stream, last_audio_stream, last_subtitle_stream;
306 SDL_cond *continue_read_thread;
309 /* options specified by the user */
310 static AVInputFormat *file_iformat;
311 static const char *input_filename;
312 static const char *window_title;
313 static int default_width = 640;
314 static int default_height = 480;
315 static int screen_width = 0;
316 static int screen_height = 0;
317 static int audio_disable;
318 static int video_disable;
319 static int subtitle_disable;
320 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
321 static int seek_by_bytes = -1;
322 static int display_disable;
323 static int borderless;
324 static int startup_volume = 100;
325 static int show_status = 1;
326 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
327 static int64_t start_time = AV_NOPTS_VALUE;
328 static int64_t duration = AV_NOPTS_VALUE;
330 static int genpts = 0;
331 static int lowres = 0;
332 static int decoder_reorder_pts = -1;
334 static int exit_on_keydown;
335 static int exit_on_mousedown;
337 static int framedrop = -1;
338 static int infinite_buffer = -1;
339 static enum ShowMode show_mode = SHOW_MODE_NONE;
340 static const char *audio_codec_name;
341 static const char *subtitle_codec_name;
342 static const char *video_codec_name;
343 double rdftspeed = 0.02;
344 static int64_t cursor_last_shown;
345 static int cursor_hidden = 0;
347 static const char **vfilters_list = NULL;
348 static int nb_vfilters = 0;
349 static char *afilters = NULL;
351 static int autorotate = 1;
353 /* current context */
354 static int is_full_screen;
355 static int64_t audio_callback_time;
357 static AVPacket flush_pkt;
359 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
361 static SDL_Window *window;
362 static SDL_Renderer *renderer;
365 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
367 GROW_ARRAY(vfilters_list, nb_vfilters);
368 vfilters_list[nb_vfilters - 1] = arg;
374 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
375 enum AVSampleFormat fmt2, int64_t channel_count2)
377 /* If channel count == 1, planar and non-planar formats are the same */
378 if (channel_count1 == 1 && channel_count2 == 1)
379 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
381 return channel_count1 != channel_count2 || fmt1 != fmt2;
385 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
387 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
388 return channel_layout;
393 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
395 MyAVPacketList *pkt1;
397 if (q->abort_request)
400 pkt1 = av_malloc(sizeof(MyAVPacketList));
405 if (pkt == &flush_pkt)
407 pkt1->serial = q->serial;
412 q->last_pkt->next = pkt1;
415 q->size += pkt1->pkt.size + sizeof(*pkt1);
416 q->duration += pkt1->pkt.duration;
417 /* XXX: should duplicate packet data in DV case */
418 SDL_CondSignal(q->cond);
422 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
426 SDL_LockMutex(q->mutex);
427 ret = packet_queue_put_private(q, pkt);
428 SDL_UnlockMutex(q->mutex);
430 if (pkt != &flush_pkt && ret < 0)
431 av_packet_unref(pkt);
436 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
438 AVPacket pkt1, *pkt = &pkt1;
442 pkt->stream_index = stream_index;
443 return packet_queue_put(q, pkt);
446 /* packet queue handling */
447 static int packet_queue_init(PacketQueue *q)
449 memset(q, 0, sizeof(PacketQueue));
450 q->mutex = SDL_CreateMutex();
452 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
453 return AVERROR(ENOMEM);
455 q->cond = SDL_CreateCond();
457 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
458 return AVERROR(ENOMEM);
460 q->abort_request = 1;
464 static void packet_queue_flush(PacketQueue *q)
466 MyAVPacketList *pkt, *pkt1;
468 SDL_LockMutex(q->mutex);
469 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
471 av_packet_unref(&pkt->pkt);
479 SDL_UnlockMutex(q->mutex);
482 static void packet_queue_destroy(PacketQueue *q)
484 packet_queue_flush(q);
485 SDL_DestroyMutex(q->mutex);
486 SDL_DestroyCond(q->cond);
489 static void packet_queue_abort(PacketQueue *q)
491 SDL_LockMutex(q->mutex);
493 q->abort_request = 1;
495 SDL_CondSignal(q->cond);
497 SDL_UnlockMutex(q->mutex);
500 static void packet_queue_start(PacketQueue *q)
502 SDL_LockMutex(q->mutex);
503 q->abort_request = 0;
504 packet_queue_put_private(q, &flush_pkt);
505 SDL_UnlockMutex(q->mutex);
508 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
509 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
511 MyAVPacketList *pkt1;
514 SDL_LockMutex(q->mutex);
517 if (q->abort_request) {
524 q->first_pkt = pkt1->next;
528 q->size -= pkt1->pkt.size + sizeof(*pkt1);
529 q->duration -= pkt1->pkt.duration;
532 *serial = pkt1->serial;
540 SDL_CondWait(q->cond, q->mutex);
543 SDL_UnlockMutex(q->mutex);
547 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
548 memset(d, 0, sizeof(Decoder));
551 d->empty_queue_cond = empty_queue_cond;
552 d->start_pts = AV_NOPTS_VALUE;
556 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
557 int ret = AVERROR(EAGAIN);
562 if (d->queue->serial == d->pkt_serial) {
564 if (d->queue->abort_request)
567 switch (d->avctx->codec_type) {
568 case AVMEDIA_TYPE_VIDEO:
569 ret = avcodec_receive_frame(d->avctx, frame);
571 if (decoder_reorder_pts == -1) {
572 frame->pts = av_frame_get_best_effort_timestamp(frame);
573 } else if (!decoder_reorder_pts) {
574 frame->pts = frame->pkt_dts;
578 case AVMEDIA_TYPE_AUDIO:
579 ret = avcodec_receive_frame(d->avctx, frame);
581 AVRational tb = (AVRational){1, frame->sample_rate};
582 if (frame->pts != AV_NOPTS_VALUE)
583 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
584 else if (d->next_pts != AV_NOPTS_VALUE)
585 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
586 if (frame->pts != AV_NOPTS_VALUE) {
587 d->next_pts = frame->pts + frame->nb_samples;
593 if (ret == AVERROR_EOF) {
594 d->finished = d->pkt_serial;
595 avcodec_flush_buffers(d->avctx);
600 } while (ret != AVERROR(EAGAIN));
604 if (d->queue->nb_packets == 0)
605 SDL_CondSignal(d->empty_queue_cond);
606 if (d->packet_pending) {
607 av_packet_move_ref(&pkt, &d->pkt);
608 d->packet_pending = 0;
610 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
613 } while (d->queue->serial != d->pkt_serial);
615 if (pkt.data == flush_pkt.data) {
616 avcodec_flush_buffers(d->avctx);
618 d->next_pts = d->start_pts;
619 d->next_pts_tb = d->start_pts_tb;
621 if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
623 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
625 ret = AVERROR(EAGAIN);
627 if (got_frame && !pkt.data) {
628 d->packet_pending = 1;
629 av_packet_move_ref(&d->pkt, &pkt);
631 ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
634 if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
635 av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
636 d->packet_pending = 1;
637 av_packet_move_ref(&d->pkt, &pkt);
640 av_packet_unref(&pkt);
645 static void decoder_destroy(Decoder *d) {
646 av_packet_unref(&d->pkt);
647 avcodec_free_context(&d->avctx);
650 static void frame_queue_unref_item(Frame *vp)
652 av_frame_unref(vp->frame);
653 avsubtitle_free(&vp->sub);
656 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
659 memset(f, 0, sizeof(FrameQueue));
660 if (!(f->mutex = SDL_CreateMutex())) {
661 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
662 return AVERROR(ENOMEM);
664 if (!(f->cond = SDL_CreateCond())) {
665 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
666 return AVERROR(ENOMEM);
669 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
670 f->keep_last = !!keep_last;
671 for (i = 0; i < f->max_size; i++)
672 if (!(f->queue[i].frame = av_frame_alloc()))
673 return AVERROR(ENOMEM);
677 static void frame_queue_destory(FrameQueue *f)
680 for (i = 0; i < f->max_size; i++) {
681 Frame *vp = &f->queue[i];
682 frame_queue_unref_item(vp);
683 av_frame_free(&vp->frame);
685 SDL_DestroyMutex(f->mutex);
686 SDL_DestroyCond(f->cond);
689 static void frame_queue_signal(FrameQueue *f)
691 SDL_LockMutex(f->mutex);
692 SDL_CondSignal(f->cond);
693 SDL_UnlockMutex(f->mutex);
696 static Frame *frame_queue_peek(FrameQueue *f)
698 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
701 static Frame *frame_queue_peek_next(FrameQueue *f)
703 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
706 static Frame *frame_queue_peek_last(FrameQueue *f)
708 return &f->queue[f->rindex];
711 static Frame *frame_queue_peek_writable(FrameQueue *f)
713 /* wait until we have space to put a new frame */
714 SDL_LockMutex(f->mutex);
715 while (f->size >= f->max_size &&
716 !f->pktq->abort_request) {
717 SDL_CondWait(f->cond, f->mutex);
719 SDL_UnlockMutex(f->mutex);
721 if (f->pktq->abort_request)
724 return &f->queue[f->windex];
727 static Frame *frame_queue_peek_readable(FrameQueue *f)
729 /* wait until we have a readable a new frame */
730 SDL_LockMutex(f->mutex);
731 while (f->size - f->rindex_shown <= 0 &&
732 !f->pktq->abort_request) {
733 SDL_CondWait(f->cond, f->mutex);
735 SDL_UnlockMutex(f->mutex);
737 if (f->pktq->abort_request)
740 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
743 static void frame_queue_push(FrameQueue *f)
745 if (++f->windex == f->max_size)
747 SDL_LockMutex(f->mutex);
749 SDL_CondSignal(f->cond);
750 SDL_UnlockMutex(f->mutex);
753 static void frame_queue_next(FrameQueue *f)
755 if (f->keep_last && !f->rindex_shown) {
759 frame_queue_unref_item(&f->queue[f->rindex]);
760 if (++f->rindex == f->max_size)
762 SDL_LockMutex(f->mutex);
764 SDL_CondSignal(f->cond);
765 SDL_UnlockMutex(f->mutex);
768 /* return the number of undisplayed frames in the queue */
769 static int frame_queue_nb_remaining(FrameQueue *f)
771 return f->size - f->rindex_shown;
774 /* return last shown position */
775 static int64_t frame_queue_last_pos(FrameQueue *f)
777 Frame *fp = &f->queue[f->rindex];
778 if (f->rindex_shown && fp->serial == f->pktq->serial)
784 static void decoder_abort(Decoder *d, FrameQueue *fq)
786 packet_queue_abort(d->queue);
787 frame_queue_signal(fq);
788 SDL_WaitThread(d->decoder_tid, NULL);
789 d->decoder_tid = NULL;
790 packet_queue_flush(d->queue);
793 static inline void fill_rectangle(int x, int y, int w, int h)
801 SDL_RenderFillRect(renderer, &rect);
804 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
808 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
811 SDL_DestroyTexture(*texture);
812 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
814 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
817 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
819 memset(pixels, 0, pitch * new_height);
820 SDL_UnlockTexture(*texture);
826 static void calculate_display_rect(SDL_Rect *rect,
827 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
828 int pic_width, int pic_height, AVRational pic_sar)
831 int width, height, x, y;
833 if (pic_sar.num == 0)
836 aspect_ratio = av_q2d(pic_sar);
838 if (aspect_ratio <= 0.0)
840 aspect_ratio *= (float)pic_width / (float)pic_height;
842 /* XXX: we suppose the screen has a 1.0 pixel ratio */
844 width = lrint(height * aspect_ratio) & ~1;
845 if (width > scr_width) {
847 height = lrint(width / aspect_ratio) & ~1;
849 x = (scr_width - width) / 2;
850 y = (scr_height - height) / 2;
851 rect->x = scr_xleft + x;
852 rect->y = scr_ytop + y;
853 rect->w = FFMAX(width, 1);
854 rect->h = FFMAX(height, 1);
857 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
859 switch (frame->format) {
860 case AV_PIX_FMT_YUV420P:
861 if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
862 av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
865 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
866 frame->data[1], frame->linesize[1],
867 frame->data[2], frame->linesize[2]);
869 case AV_PIX_FMT_BGRA:
870 if (frame->linesize[0] < 0) {
871 ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
873 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
877 /* This should only happen if we are not using avfilter... */
878 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
879 frame->width, frame->height, frame->format, frame->width, frame->height,
880 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
881 if (*img_convert_ctx != NULL) {
884 if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) {
885 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
886 0, frame->height, pixels, pitch);
887 SDL_UnlockTexture(tex);
890 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
898 static void video_image_display(VideoState *is)
904 vp = frame_queue_peek_last(&is->pictq);
905 if (is->subtitle_st) {
906 if (frame_queue_nb_remaining(&is->subpq) > 0) {
907 sp = frame_queue_peek(&is->subpq);
909 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
914 if (!sp->width || !sp->height) {
915 sp->width = vp->width;
916 sp->height = vp->height;
918 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
921 for (i = 0; i < sp->sub.num_rects; i++) {
922 AVSubtitleRect *sub_rect = sp->sub.rects[i];
924 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
925 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
926 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
927 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
929 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
930 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
931 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
932 0, NULL, NULL, NULL);
933 if (!is->sub_convert_ctx) {
934 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
937 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
938 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
939 0, sub_rect->h, pixels, pitch);
940 SDL_UnlockTexture(is->sub_texture);
950 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
953 int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888;
954 if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0)
956 if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
959 vp->flip_v = vp->frame->linesize[0] < 0;
962 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
964 #if USE_ONEPASS_SUBTITLE_RENDER
965 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
968 double xratio = (double)rect.w / (double)sp->width;
969 double yratio = (double)rect.h / (double)sp->height;
970 for (i = 0; i < sp->sub.num_rects; i++) {
971 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
972 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
973 .y = rect.y + sub_rect->y * yratio,
974 .w = sub_rect->w * xratio,
975 .h = sub_rect->h * yratio};
976 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
982 static inline int compute_mod(int a, int b)
984 return a < 0 ? a%b + b : a%b;
987 static void video_audio_display(VideoState *s)
989 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
990 int ch, channels, h, h2;
992 int rdft_bits, nb_freq;
994 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
996 nb_freq = 1 << (rdft_bits - 1);
998 /* compute display index : center on currently output samples */
999 channels = s->audio_tgt.channels;
1000 nb_display_channels = channels;
1002 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1004 delay = s->audio_write_buf_size;
1007 /* to be more precise, we take into account the time spent since
1008 the last buffer computation */
1009 if (audio_callback_time) {
1010 time_diff = av_gettime_relative() - audio_callback_time;
1011 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1014 delay += 2 * data_used;
1015 if (delay < data_used)
1018 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1019 if (s->show_mode == SHOW_MODE_WAVES) {
1021 for (i = 0; i < 1000; i += channels) {
1022 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1023 int a = s->sample_array[idx];
1024 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1025 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1026 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1028 if (h < score && (b ^ c) < 0) {
1035 s->last_i_start = i_start;
1037 i_start = s->last_i_start;
1040 if (s->show_mode == SHOW_MODE_WAVES) {
1041 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1043 /* total height for one channel */
1044 h = s->height / nb_display_channels;
1045 /* graph height / 2 */
1047 for (ch = 0; ch < nb_display_channels; ch++) {
1049 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1050 for (x = 0; x < s->width; x++) {
1051 y = (s->sample_array[i] * h2) >> 15;
1058 fill_rectangle(s->xleft + x, ys, 1, y);
1060 if (i >= SAMPLE_ARRAY_SIZE)
1061 i -= SAMPLE_ARRAY_SIZE;
1065 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1067 for (ch = 1; ch < nb_display_channels; ch++) {
1068 y = s->ytop + ch * h;
1069 fill_rectangle(s->xleft, y, s->width, 1);
1072 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1075 nb_display_channels= FFMIN(nb_display_channels, 2);
1076 if (rdft_bits != s->rdft_bits) {
1077 av_rdft_end(s->rdft);
1078 av_free(s->rdft_data);
1079 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1080 s->rdft_bits = rdft_bits;
1081 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1083 if (!s->rdft || !s->rdft_data){
1084 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1085 s->show_mode = SHOW_MODE_WAVES;
1088 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1091 for (ch = 0; ch < nb_display_channels; ch++) {
1092 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1094 for (x = 0; x < 2 * nb_freq; x++) {
1095 double w = (x-nb_freq) * (1.0 / nb_freq);
1096 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1098 if (i >= SAMPLE_ARRAY_SIZE)
1099 i -= SAMPLE_ARRAY_SIZE;
1101 av_rdft_calc(s->rdft, data[ch]);
1103 /* Least efficient way to do this, we should of course
1104 * directly access it but it is more than fast enough. */
1105 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1107 pixels += pitch * s->height;
1108 for (y = 0; y < s->height; y++) {
1109 double w = 1 / sqrt(nb_freq);
1110 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]));
1111 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1116 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1118 SDL_UnlockTexture(s->vis_texture);
1120 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1124 if (s->xpos >= s->width)
1129 static void stream_component_close(VideoState *is, int stream_index)
1131 AVFormatContext *ic = is->ic;
1132 AVCodecParameters *codecpar;
1134 if (stream_index < 0 || stream_index >= ic->nb_streams)
1136 codecpar = ic->streams[stream_index]->codecpar;
1138 switch (codecpar->codec_type) {
1139 case AVMEDIA_TYPE_AUDIO:
1140 decoder_abort(&is->auddec, &is->sampq);
1142 decoder_destroy(&is->auddec);
1143 swr_free(&is->swr_ctx);
1144 av_freep(&is->audio_buf1);
1145 is->audio_buf1_size = 0;
1146 is->audio_buf = NULL;
1149 av_rdft_end(is->rdft);
1150 av_freep(&is->rdft_data);
1155 case AVMEDIA_TYPE_VIDEO:
1156 decoder_abort(&is->viddec, &is->pictq);
1157 decoder_destroy(&is->viddec);
1159 case AVMEDIA_TYPE_SUBTITLE:
1160 decoder_abort(&is->subdec, &is->subpq);
1161 decoder_destroy(&is->subdec);
1167 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1168 switch (codecpar->codec_type) {
1169 case AVMEDIA_TYPE_AUDIO:
1170 is->audio_st = NULL;
1171 is->audio_stream = -1;
1173 case AVMEDIA_TYPE_VIDEO:
1174 is->video_st = NULL;
1175 is->video_stream = -1;
1177 case AVMEDIA_TYPE_SUBTITLE:
1178 is->subtitle_st = NULL;
1179 is->subtitle_stream = -1;
1186 static void stream_close(VideoState *is)
1188 /* XXX: use a special url_shutdown call to abort parse cleanly */
1189 is->abort_request = 1;
1190 SDL_WaitThread(is->read_tid, NULL);
1192 /* close each stream */
1193 if (is->audio_stream >= 0)
1194 stream_component_close(is, is->audio_stream);
1195 if (is->video_stream >= 0)
1196 stream_component_close(is, is->video_stream);
1197 if (is->subtitle_stream >= 0)
1198 stream_component_close(is, is->subtitle_stream);
1200 avformat_close_input(&is->ic);
1202 packet_queue_destroy(&is->videoq);
1203 packet_queue_destroy(&is->audioq);
1204 packet_queue_destroy(&is->subtitleq);
1206 /* free all pictures */
1207 frame_queue_destory(&is->pictq);
1208 frame_queue_destory(&is->sampq);
1209 frame_queue_destory(&is->subpq);
1210 SDL_DestroyCond(is->continue_read_thread);
1211 sws_freeContext(is->img_convert_ctx);
1212 sws_freeContext(is->sub_convert_ctx);
1213 av_free(is->filename);
1214 if (is->vis_texture)
1215 SDL_DestroyTexture(is->vis_texture);
1216 if (is->vid_texture)
1217 SDL_DestroyTexture(is->vid_texture);
1218 if (is->sub_texture)
1219 SDL_DestroyTexture(is->sub_texture);
1223 static void do_exit(VideoState *is)
1229 SDL_DestroyRenderer(renderer);
1231 SDL_DestroyWindow(window);
1232 av_lockmgr_register(NULL);
1235 av_freep(&vfilters_list);
1237 avformat_network_deinit();
1241 av_log(NULL, AV_LOG_QUIET, "%s", "");
1245 static void sigterm_handler(int sig)
1250 static void set_default_window_size(int width, int height, AVRational sar)
1253 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1254 default_width = rect.w;
1255 default_height = rect.h;
1258 static int video_open(VideoState *is)
1271 int flags = SDL_WINDOW_SHOWN;
1273 window_title = input_filename;
1275 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1277 flags |= SDL_WINDOW_BORDERLESS;
1279 flags |= SDL_WINDOW_RESIZABLE;
1280 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1281 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1283 SDL_RendererInfo info;
1284 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1286 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1287 renderer = SDL_CreateRenderer(window, -1, 0);
1290 if (!SDL_GetRendererInfo(renderer, &info))
1291 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1295 SDL_SetWindowSize(window, w, h);
1298 if (!window || !renderer) {
1299 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1309 /* display the current picture, if any */
1310 static void video_display(VideoState *is)
1315 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1316 SDL_RenderClear(renderer);
1317 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1318 video_audio_display(is);
1319 else if (is->video_st)
1320 video_image_display(is);
1321 SDL_RenderPresent(renderer);
1324 static double get_clock(Clock *c)
1326 if (*c->queue_serial != c->serial)
1331 double time = av_gettime_relative() / 1000000.0;
1332 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1336 static void set_clock_at(Clock *c, double pts, int serial, double time)
1339 c->last_updated = time;
1340 c->pts_drift = c->pts - time;
1344 static void set_clock(Clock *c, double pts, int serial)
1346 double time = av_gettime_relative() / 1000000.0;
1347 set_clock_at(c, pts, serial, time);
1350 static void set_clock_speed(Clock *c, double speed)
1352 set_clock(c, get_clock(c), c->serial);
1356 static void init_clock(Clock *c, int *queue_serial)
1360 c->queue_serial = queue_serial;
1361 set_clock(c, NAN, -1);
1364 static void sync_clock_to_slave(Clock *c, Clock *slave)
1366 double clock = get_clock(c);
1367 double slave_clock = get_clock(slave);
1368 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1369 set_clock(c, slave_clock, slave->serial);
1372 static int get_master_sync_type(VideoState *is) {
1373 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1375 return AV_SYNC_VIDEO_MASTER;
1377 return AV_SYNC_AUDIO_MASTER;
1378 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1380 return AV_SYNC_AUDIO_MASTER;
1382 return AV_SYNC_EXTERNAL_CLOCK;
1384 return AV_SYNC_EXTERNAL_CLOCK;
1388 /* get the current master clock value */
1389 static double get_master_clock(VideoState *is)
1393 switch (get_master_sync_type(is)) {
1394 case AV_SYNC_VIDEO_MASTER:
1395 val = get_clock(&is->vidclk);
1397 case AV_SYNC_AUDIO_MASTER:
1398 val = get_clock(&is->audclk);
1401 val = get_clock(&is->extclk);
1407 static void check_external_clock_speed(VideoState *is) {
1408 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1409 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1410 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1411 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1412 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1413 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1415 double speed = is->extclk.speed;
1417 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1421 /* seek in the stream */
1422 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1424 if (!is->seek_req) {
1427 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1429 is->seek_flags |= AVSEEK_FLAG_BYTE;
1431 SDL_CondSignal(is->continue_read_thread);
1435 /* pause or resume the video */
1436 static void stream_toggle_pause(VideoState *is)
1439 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1440 if (is->read_pause_return != AVERROR(ENOSYS)) {
1441 is->vidclk.paused = 0;
1443 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1445 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1446 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1449 static void toggle_pause(VideoState *is)
1451 stream_toggle_pause(is);
1455 static void toggle_mute(VideoState *is)
1457 is->muted = !is->muted;
1460 static void update_volume(VideoState *is, int sign, double step)
1462 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1463 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1464 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1467 static void step_to_next_frame(VideoState *is)
1469 /* if the stream is paused unpause it, then step */
1471 stream_toggle_pause(is);
1475 static double compute_target_delay(double delay, VideoState *is)
1477 double sync_threshold, diff = 0;
1479 /* update delay to follow master synchronisation source */
1480 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1481 /* if video is slave, we try to correct big delays by
1482 duplicating or deleting a frame */
1483 diff = get_clock(&is->vidclk) - get_master_clock(is);
1485 /* skip or repeat frame. We take into account the
1486 delay to compute the threshold. I still don't know
1487 if it is the best guess */
1488 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1489 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1490 if (diff <= -sync_threshold)
1491 delay = FFMAX(0, delay + diff);
1492 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1493 delay = delay + diff;
1494 else if (diff >= sync_threshold)
1499 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1505 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1506 if (vp->serial == nextvp->serial) {
1507 double duration = nextvp->pts - vp->pts;
1508 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1509 return vp->duration;
1517 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1518 /* update current video pts */
1519 set_clock(&is->vidclk, pts, serial);
1520 sync_clock_to_slave(&is->extclk, &is->vidclk);
1523 /* called to display each frame */
1524 static void video_refresh(void *opaque, double *remaining_time)
1526 VideoState *is = opaque;
1531 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1532 check_external_clock_speed(is);
1534 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1535 time = av_gettime_relative() / 1000000.0;
1536 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1538 is->last_vis_time = time;
1540 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1545 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1546 // nothing to do, no picture to display in the queue
1548 double last_duration, duration, delay;
1551 /* dequeue the picture */
1552 lastvp = frame_queue_peek_last(&is->pictq);
1553 vp = frame_queue_peek(&is->pictq);
1555 if (vp->serial != is->videoq.serial) {
1556 frame_queue_next(&is->pictq);
1560 if (lastvp->serial != vp->serial)
1561 is->frame_timer = av_gettime_relative() / 1000000.0;
1566 /* compute nominal last_duration */
1567 last_duration = vp_duration(is, lastvp, vp);
1568 delay = compute_target_delay(last_duration, is);
1570 time= av_gettime_relative()/1000000.0;
1571 if (time < is->frame_timer + delay) {
1572 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1576 is->frame_timer += delay;
1577 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1578 is->frame_timer = time;
1580 SDL_LockMutex(is->pictq.mutex);
1581 if (!isnan(vp->pts))
1582 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1583 SDL_UnlockMutex(is->pictq.mutex);
1585 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1586 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1587 duration = vp_duration(is, vp, nextvp);
1588 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1589 is->frame_drops_late++;
1590 frame_queue_next(&is->pictq);
1595 if (is->subtitle_st) {
1596 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1597 sp = frame_queue_peek(&is->subpq);
1599 if (frame_queue_nb_remaining(&is->subpq) > 1)
1600 sp2 = frame_queue_peek_next(&is->subpq);
1604 if (sp->serial != is->subtitleq.serial
1605 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1606 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1610 for (i = 0; i < sp->sub.num_rects; i++) {
1611 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1615 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1616 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1617 memset(pixels, 0, sub_rect->w << 2);
1618 SDL_UnlockTexture(is->sub_texture);
1622 frame_queue_next(&is->subpq);
1629 frame_queue_next(&is->pictq);
1630 is->force_refresh = 1;
1632 if (is->step && !is->paused)
1633 stream_toggle_pause(is);
1636 /* display picture */
1637 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1640 is->force_refresh = 0;
1642 static int64_t last_time;
1644 int aqsize, vqsize, sqsize;
1647 cur_time = av_gettime_relative();
1648 if (!last_time || (cur_time - last_time) >= 30000) {
1653 aqsize = is->audioq.size;
1655 vqsize = is->videoq.size;
1656 if (is->subtitle_st)
1657 sqsize = is->subtitleq.size;
1659 if (is->audio_st && is->video_st)
1660 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1661 else if (is->video_st)
1662 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1663 else if (is->audio_st)
1664 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1665 av_log(NULL, AV_LOG_INFO,
1666 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1667 get_master_clock(is),
1668 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1670 is->frame_drops_early + is->frame_drops_late,
1674 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1675 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1677 last_time = cur_time;
1682 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1686 #if defined(DEBUG_SYNC)
1687 printf("frame_type=%c pts=%0.3f\n",
1688 av_get_picture_type_char(src_frame->pict_type), pts);
1691 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1694 vp->sar = src_frame->sample_aspect_ratio;
1697 vp->width = src_frame->width;
1698 vp->height = src_frame->height;
1699 vp->format = src_frame->format;
1702 vp->duration = duration;
1704 vp->serial = serial;
1706 set_default_window_size(vp->width, vp->height, vp->sar);
1708 av_frame_move_ref(vp->frame, src_frame);
1709 frame_queue_push(&is->pictq);
1713 static int get_video_frame(VideoState *is, AVFrame *frame)
1717 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1723 if (frame->pts != AV_NOPTS_VALUE)
1724 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1726 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1728 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1729 if (frame->pts != AV_NOPTS_VALUE) {
1730 double diff = dpts - get_master_clock(is);
1731 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1732 diff - is->frame_last_filter_delay < 0 &&
1733 is->viddec.pkt_serial == is->vidclk.serial &&
1734 is->videoq.nb_packets) {
1735 is->frame_drops_early++;
1736 av_frame_unref(frame);
1747 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1748 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1751 int nb_filters = graph->nb_filters;
1752 AVFilterInOut *outputs = NULL, *inputs = NULL;
1755 outputs = avfilter_inout_alloc();
1756 inputs = avfilter_inout_alloc();
1757 if (!outputs || !inputs) {
1758 ret = AVERROR(ENOMEM);
1762 outputs->name = av_strdup("in");
1763 outputs->filter_ctx = source_ctx;
1764 outputs->pad_idx = 0;
1765 outputs->next = NULL;
1767 inputs->name = av_strdup("out");
1768 inputs->filter_ctx = sink_ctx;
1769 inputs->pad_idx = 0;
1770 inputs->next = NULL;
1772 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1775 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1779 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1780 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1781 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1783 ret = avfilter_graph_config(graph, NULL);
1785 avfilter_inout_free(&outputs);
1786 avfilter_inout_free(&inputs);
1790 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1792 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1793 char sws_flags_str[512] = "";
1794 char buffersrc_args[256];
1796 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1797 AVCodecParameters *codecpar = is->video_st->codecpar;
1798 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1799 AVDictionaryEntry *e = NULL;
1801 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1802 if (!strcmp(e->key, "sws_flags")) {
1803 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1805 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1807 if (strlen(sws_flags_str))
1808 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1810 graph->scale_sws_opts = av_strdup(sws_flags_str);
1812 snprintf(buffersrc_args, sizeof(buffersrc_args),
1813 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1814 frame->width, frame->height, frame->format,
1815 is->video_st->time_base.num, is->video_st->time_base.den,
1816 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1817 if (fr.num && fr.den)
1818 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1820 if ((ret = avfilter_graph_create_filter(&filt_src,
1821 avfilter_get_by_name("buffer"),
1822 "ffplay_buffer", buffersrc_args, NULL,
1826 ret = avfilter_graph_create_filter(&filt_out,
1827 avfilter_get_by_name("buffersink"),
1828 "ffplay_buffersink", NULL, NULL, graph);
1832 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1835 last_filter = filt_out;
1837 /* Note: this macro adds a filter before the lastly added filter, so the
1838 * processing order of the filters is in reverse */
1839 #define INSERT_FILT(name, arg) do { \
1840 AVFilterContext *filt_ctx; \
1842 ret = avfilter_graph_create_filter(&filt_ctx, \
1843 avfilter_get_by_name(name), \
1844 "ffplay_" name, arg, NULL, graph); \
1848 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1852 last_filter = filt_ctx; \
1856 double theta = get_rotation(is->video_st);
1858 if (fabs(theta - 90) < 1.0) {
1859 INSERT_FILT("transpose", "clock");
1860 } else if (fabs(theta - 180) < 1.0) {
1861 INSERT_FILT("hflip", NULL);
1862 INSERT_FILT("vflip", NULL);
1863 } else if (fabs(theta - 270) < 1.0) {
1864 INSERT_FILT("transpose", "cclock");
1865 } else if (fabs(theta) > 1.0) {
1866 char rotate_buf[64];
1867 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1868 INSERT_FILT("rotate", rotate_buf);
1872 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1875 is->in_video_filter = filt_src;
1876 is->out_video_filter = filt_out;
1882 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1884 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1885 int sample_rates[2] = { 0, -1 };
1886 int64_t channel_layouts[2] = { 0, -1 };
1887 int channels[2] = { 0, -1 };
1888 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1889 char aresample_swr_opts[512] = "";
1890 AVDictionaryEntry *e = NULL;
1891 char asrc_args[256];
1894 avfilter_graph_free(&is->agraph);
1895 if (!(is->agraph = avfilter_graph_alloc()))
1896 return AVERROR(ENOMEM);
1898 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1899 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1900 if (strlen(aresample_swr_opts))
1901 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1902 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1904 ret = snprintf(asrc_args, sizeof(asrc_args),
1905 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1906 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1907 is->audio_filter_src.channels,
1908 1, is->audio_filter_src.freq);
1909 if (is->audio_filter_src.channel_layout)
1910 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1911 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1913 ret = avfilter_graph_create_filter(&filt_asrc,
1914 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1915 asrc_args, NULL, is->agraph);
1920 ret = avfilter_graph_create_filter(&filt_asink,
1921 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1922 NULL, NULL, is->agraph);
1926 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1928 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1931 if (force_output_format) {
1932 channel_layouts[0] = is->audio_tgt.channel_layout;
1933 channels [0] = is->audio_tgt.channels;
1934 sample_rates [0] = is->audio_tgt.freq;
1935 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1937 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1939 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1941 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1946 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1949 is->in_audio_filter = filt_asrc;
1950 is->out_audio_filter = filt_asink;
1954 avfilter_graph_free(&is->agraph);
1957 #endif /* CONFIG_AVFILTER */
1959 static int audio_thread(void *arg)
1961 VideoState *is = arg;
1962 AVFrame *frame = av_frame_alloc();
1965 int last_serial = -1;
1966 int64_t dec_channel_layout;
1974 return AVERROR(ENOMEM);
1977 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1981 tb = (AVRational){1, frame->sample_rate};
1984 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
1987 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
1988 frame->format, av_frame_get_channels(frame)) ||
1989 is->audio_filter_src.channel_layout != dec_channel_layout ||
1990 is->audio_filter_src.freq != frame->sample_rate ||
1991 is->auddec.pkt_serial != last_serial;
1994 char buf1[1024], buf2[1024];
1995 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
1996 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
1997 av_log(NULL, AV_LOG_DEBUG,
1998 "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",
1999 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2000 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2002 is->audio_filter_src.fmt = frame->format;
2003 is->audio_filter_src.channels = av_frame_get_channels(frame);
2004 is->audio_filter_src.channel_layout = dec_channel_layout;
2005 is->audio_filter_src.freq = frame->sample_rate;
2006 last_serial = is->auddec.pkt_serial;
2008 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2012 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2015 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2016 tb = av_buffersink_get_time_base(is->out_audio_filter);
2018 if (!(af = frame_queue_peek_writable(&is->sampq)))
2021 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2022 af->pos = av_frame_get_pkt_pos(frame);
2023 af->serial = is->auddec.pkt_serial;
2024 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2026 av_frame_move_ref(af->frame, frame);
2027 frame_queue_push(&is->sampq);
2030 if (is->audioq.serial != is->auddec.pkt_serial)
2033 if (ret == AVERROR_EOF)
2034 is->auddec.finished = is->auddec.pkt_serial;
2037 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2040 avfilter_graph_free(&is->agraph);
2042 av_frame_free(&frame);
2046 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2048 packet_queue_start(d->queue);
2049 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2050 if (!d->decoder_tid) {
2051 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2052 return AVERROR(ENOMEM);
2057 static int video_thread(void *arg)
2059 VideoState *is = arg;
2060 AVFrame *frame = av_frame_alloc();
2064 AVRational tb = is->video_st->time_base;
2065 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2068 AVFilterGraph *graph = avfilter_graph_alloc();
2069 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2072 enum AVPixelFormat last_format = -2;
2073 int last_serial = -1;
2074 int last_vfilter_idx = 0;
2076 av_frame_free(&frame);
2077 return AVERROR(ENOMEM);
2084 avfilter_graph_free(&graph);
2086 return AVERROR(ENOMEM);
2090 ret = get_video_frame(is, frame);
2097 if ( last_w != frame->width
2098 || last_h != frame->height
2099 || last_format != frame->format
2100 || last_serial != is->viddec.pkt_serial
2101 || last_vfilter_idx != is->vfilter_idx) {
2102 av_log(NULL, AV_LOG_DEBUG,
2103 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2105 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2106 frame->width, frame->height,
2107 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2108 avfilter_graph_free(&graph);
2109 graph = avfilter_graph_alloc();
2110 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2112 event.type = FF_QUIT_EVENT;
2113 event.user.data1 = is;
2114 SDL_PushEvent(&event);
2117 filt_in = is->in_video_filter;
2118 filt_out = is->out_video_filter;
2119 last_w = frame->width;
2120 last_h = frame->height;
2121 last_format = frame->format;
2122 last_serial = is->viddec.pkt_serial;
2123 last_vfilter_idx = is->vfilter_idx;
2124 frame_rate = av_buffersink_get_frame_rate(filt_out);
2127 ret = av_buffersrc_add_frame(filt_in, frame);
2132 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2134 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2136 if (ret == AVERROR_EOF)
2137 is->viddec.finished = is->viddec.pkt_serial;
2142 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2143 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2144 is->frame_last_filter_delay = 0;
2145 tb = av_buffersink_get_time_base(filt_out);
2147 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2148 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2149 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2150 av_frame_unref(frame);
2160 avfilter_graph_free(&graph);
2162 av_frame_free(&frame);
2166 static int subtitle_thread(void *arg)
2168 VideoState *is = arg;
2174 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2177 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2182 if (got_subtitle && sp->sub.format == 0) {
2183 if (sp->sub.pts != AV_NOPTS_VALUE)
2184 pts = sp->sub.pts / (double)AV_TIME_BASE;
2186 sp->serial = is->subdec.pkt_serial;
2187 sp->width = is->subdec.avctx->width;
2188 sp->height = is->subdec.avctx->height;
2191 /* now we can update the picture count */
2192 frame_queue_push(&is->subpq);
2193 } else if (got_subtitle) {
2194 avsubtitle_free(&sp->sub);
2200 /* copy samples for viewing in editor window */
2201 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2205 size = samples_size / sizeof(short);
2207 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2210 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2212 is->sample_array_index += len;
2213 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2214 is->sample_array_index = 0;
2219 /* return the wanted number of samples to get better sync if sync_type is video
2220 * or external master clock */
2221 static int synchronize_audio(VideoState *is, int nb_samples)
2223 int wanted_nb_samples = nb_samples;
2225 /* if not master, then we try to remove or add samples to correct the clock */
2226 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2227 double diff, avg_diff;
2228 int min_nb_samples, max_nb_samples;
2230 diff = get_clock(&is->audclk) - get_master_clock(is);
2232 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2233 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2234 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2235 /* not enough measures to have a correct estimate */
2236 is->audio_diff_avg_count++;
2238 /* estimate the A-V difference */
2239 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2241 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2242 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2243 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2244 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2245 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2247 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2248 diff, avg_diff, wanted_nb_samples - nb_samples,
2249 is->audio_clock, is->audio_diff_threshold);
2252 /* too big difference : may be initial PTS errors, so
2254 is->audio_diff_avg_count = 0;
2255 is->audio_diff_cum = 0;
2259 return wanted_nb_samples;
2263 * Decode one audio frame and return its uncompressed size.
2265 * The processed audio frame is decoded, converted if required, and
2266 * stored in is->audio_buf, with size in bytes given by the return
2269 static int audio_decode_frame(VideoState *is)
2271 int data_size, resampled_data_size;
2272 int64_t dec_channel_layout;
2273 av_unused double audio_clock0;
2274 int wanted_nb_samples;
2282 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2283 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2288 if (!(af = frame_queue_peek_readable(&is->sampq)))
2290 frame_queue_next(&is->sampq);
2291 } while (af->serial != is->audioq.serial);
2293 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2294 af->frame->nb_samples,
2295 af->frame->format, 1);
2297 dec_channel_layout =
2298 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2299 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2300 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2302 if (af->frame->format != is->audio_src.fmt ||
2303 dec_channel_layout != is->audio_src.channel_layout ||
2304 af->frame->sample_rate != is->audio_src.freq ||
2305 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2306 swr_free(&is->swr_ctx);
2307 is->swr_ctx = swr_alloc_set_opts(NULL,
2308 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2309 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2311 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2312 av_log(NULL, AV_LOG_ERROR,
2313 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2314 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2315 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2316 swr_free(&is->swr_ctx);
2319 is->audio_src.channel_layout = dec_channel_layout;
2320 is->audio_src.channels = av_frame_get_channels(af->frame);
2321 is->audio_src.freq = af->frame->sample_rate;
2322 is->audio_src.fmt = af->frame->format;
2326 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2327 uint8_t **out = &is->audio_buf1;
2328 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2329 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2332 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2335 if (wanted_nb_samples != af->frame->nb_samples) {
2336 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2337 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2338 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2342 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2343 if (!is->audio_buf1)
2344 return AVERROR(ENOMEM);
2345 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2347 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2350 if (len2 == out_count) {
2351 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2352 if (swr_init(is->swr_ctx) < 0)
2353 swr_free(&is->swr_ctx);
2355 is->audio_buf = is->audio_buf1;
2356 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2358 is->audio_buf = af->frame->data[0];
2359 resampled_data_size = data_size;
2362 audio_clock0 = is->audio_clock;
2363 /* update the audio clock with the pts */
2364 if (!isnan(af->pts))
2365 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2367 is->audio_clock = NAN;
2368 is->audio_clock_serial = af->serial;
2371 static double last_clock;
2372 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2373 is->audio_clock - last_clock,
2374 is->audio_clock, audio_clock0);
2375 last_clock = is->audio_clock;
2378 return resampled_data_size;
2381 /* prepare a new audio buffer */
2382 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2384 VideoState *is = opaque;
2385 int audio_size, len1;
2387 audio_callback_time = av_gettime_relative();
2390 if (is->audio_buf_index >= is->audio_buf_size) {
2391 audio_size = audio_decode_frame(is);
2392 if (audio_size < 0) {
2393 /* if error, just output silence */
2394 is->audio_buf = NULL;
2395 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2397 if (is->show_mode != SHOW_MODE_VIDEO)
2398 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2399 is->audio_buf_size = audio_size;
2401 is->audio_buf_index = 0;
2403 len1 = is->audio_buf_size - is->audio_buf_index;
2406 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2407 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2409 memset(stream, 0, len1);
2410 if (!is->muted && is->audio_buf)
2411 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2415 is->audio_buf_index += len1;
2417 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2418 /* Let's assume the audio driver that is used by SDL has two periods. */
2419 if (!isnan(is->audio_clock)) {
2420 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);
2421 sync_clock_to_slave(&is->extclk, &is->audclk);
2425 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2427 SDL_AudioSpec wanted_spec, spec;
2429 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2430 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2431 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2433 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2435 wanted_nb_channels = atoi(env);
2436 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2438 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2439 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2440 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2442 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2443 wanted_spec.channels = wanted_nb_channels;
2444 wanted_spec.freq = wanted_sample_rate;
2445 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2446 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2449 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2450 next_sample_rate_idx--;
2451 wanted_spec.format = AUDIO_S16SYS;
2452 wanted_spec.silence = 0;
2453 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2454 wanted_spec.callback = sdl_audio_callback;
2455 wanted_spec.userdata = opaque;
2456 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2457 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2458 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2459 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2460 if (!wanted_spec.channels) {
2461 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2462 wanted_spec.channels = wanted_nb_channels;
2463 if (!wanted_spec.freq) {
2464 av_log(NULL, AV_LOG_ERROR,
2465 "No more combinations to try, audio open failed\n");
2469 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2471 if (spec.format != AUDIO_S16SYS) {
2472 av_log(NULL, AV_LOG_ERROR,
2473 "SDL advised audio format %d is not supported!\n", spec.format);
2476 if (spec.channels != wanted_spec.channels) {
2477 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2478 if (!wanted_channel_layout) {
2479 av_log(NULL, AV_LOG_ERROR,
2480 "SDL advised channel count %d is not supported!\n", spec.channels);
2485 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2486 audio_hw_params->freq = spec.freq;
2487 audio_hw_params->channel_layout = wanted_channel_layout;
2488 audio_hw_params->channels = spec.channels;
2489 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2490 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);
2491 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2492 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2498 /* open a given stream. Return 0 if OK */
2499 static int stream_component_open(VideoState *is, int stream_index)
2501 AVFormatContext *ic = is->ic;
2502 AVCodecContext *avctx;
2504 const char *forced_codec_name = NULL;
2505 AVDictionary *opts = NULL;
2506 AVDictionaryEntry *t = NULL;
2507 int sample_rate, nb_channels;
2508 int64_t channel_layout;
2510 int stream_lowres = lowres;
2512 if (stream_index < 0 || stream_index >= ic->nb_streams)
2515 avctx = avcodec_alloc_context3(NULL);
2517 return AVERROR(ENOMEM);
2519 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2522 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2524 codec = avcodec_find_decoder(avctx->codec_id);
2526 switch(avctx->codec_type){
2527 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2528 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2529 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2531 if (forced_codec_name)
2532 codec = avcodec_find_decoder_by_name(forced_codec_name);
2534 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2535 "No codec could be found with name '%s'\n", forced_codec_name);
2536 else av_log(NULL, AV_LOG_WARNING,
2537 "No codec could be found with id %d\n", avctx->codec_id);
2538 ret = AVERROR(EINVAL);
2542 avctx->codec_id = codec->id;
2543 if(stream_lowres > av_codec_get_max_lowres(codec)){
2544 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2545 av_codec_get_max_lowres(codec));
2546 stream_lowres = av_codec_get_max_lowres(codec);
2548 av_codec_set_lowres(avctx, stream_lowres);
2551 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2554 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2556 if(codec->capabilities & AV_CODEC_CAP_DR1)
2557 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2560 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2561 if (!av_dict_get(opts, "threads", NULL, 0))
2562 av_dict_set(&opts, "threads", "auto", 0);
2564 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2565 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2566 av_dict_set(&opts, "refcounted_frames", "1", 0);
2567 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2570 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2571 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2572 ret = AVERROR_OPTION_NOT_FOUND;
2577 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2578 switch (avctx->codec_type) {
2579 case AVMEDIA_TYPE_AUDIO:
2582 AVFilterContext *sink;
2584 is->audio_filter_src.freq = avctx->sample_rate;
2585 is->audio_filter_src.channels = avctx->channels;
2586 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2587 is->audio_filter_src.fmt = avctx->sample_fmt;
2588 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2590 sink = is->out_audio_filter;
2591 sample_rate = av_buffersink_get_sample_rate(sink);
2592 nb_channels = av_buffersink_get_channels(sink);
2593 channel_layout = av_buffersink_get_channel_layout(sink);
2596 sample_rate = avctx->sample_rate;
2597 nb_channels = avctx->channels;
2598 channel_layout = avctx->channel_layout;
2601 /* prepare audio output */
2602 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2604 is->audio_hw_buf_size = ret;
2605 is->audio_src = is->audio_tgt;
2606 is->audio_buf_size = 0;
2607 is->audio_buf_index = 0;
2609 /* init averaging filter */
2610 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2611 is->audio_diff_avg_count = 0;
2612 /* since we do not have a precise anough audio FIFO fullness,
2613 we correct audio sync only if larger than this threshold */
2614 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2616 is->audio_stream = stream_index;
2617 is->audio_st = ic->streams[stream_index];
2619 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2620 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2621 is->auddec.start_pts = is->audio_st->start_time;
2622 is->auddec.start_pts_tb = is->audio_st->time_base;
2624 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2628 case AVMEDIA_TYPE_VIDEO:
2629 is->video_stream = stream_index;
2630 is->video_st = ic->streams[stream_index];
2632 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2633 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2635 is->queue_attachments_req = 1;
2637 case AVMEDIA_TYPE_SUBTITLE:
2638 is->subtitle_stream = stream_index;
2639 is->subtitle_st = ic->streams[stream_index];
2641 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2642 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2651 avcodec_free_context(&avctx);
2653 av_dict_free(&opts);
2658 static int decode_interrupt_cb(void *ctx)
2660 VideoState *is = ctx;
2661 return is->abort_request;
2664 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2665 return stream_id < 0 ||
2666 queue->abort_request ||
2667 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2668 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2671 static int is_realtime(AVFormatContext *s)
2673 if( !strcmp(s->iformat->name, "rtp")
2674 || !strcmp(s->iformat->name, "rtsp")
2675 || !strcmp(s->iformat->name, "sdp")
2679 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2680 || !strncmp(s->filename, "udp:", 4)
2687 /* this thread gets the stream from the disk or the network */
2688 static int read_thread(void *arg)
2690 VideoState *is = arg;
2691 AVFormatContext *ic = NULL;
2693 int st_index[AVMEDIA_TYPE_NB];
2694 AVPacket pkt1, *pkt = &pkt1;
2695 int64_t stream_start_time;
2696 int pkt_in_play_range = 0;
2697 AVDictionaryEntry *t;
2698 AVDictionary **opts;
2699 int orig_nb_streams;
2700 SDL_mutex *wait_mutex = SDL_CreateMutex();
2701 int scan_all_pmts_set = 0;
2705 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2706 ret = AVERROR(ENOMEM);
2710 memset(st_index, -1, sizeof(st_index));
2711 is->last_video_stream = is->video_stream = -1;
2712 is->last_audio_stream = is->audio_stream = -1;
2713 is->last_subtitle_stream = is->subtitle_stream = -1;
2716 ic = avformat_alloc_context();
2718 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2719 ret = AVERROR(ENOMEM);
2722 ic->interrupt_callback.callback = decode_interrupt_cb;
2723 ic->interrupt_callback.opaque = is;
2724 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2725 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2726 scan_all_pmts_set = 1;
2728 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2730 print_error(is->filename, err);
2734 if (scan_all_pmts_set)
2735 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2737 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2738 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2739 ret = AVERROR_OPTION_NOT_FOUND;
2745 ic->flags |= AVFMT_FLAG_GENPTS;
2747 av_format_inject_global_side_data(ic);
2749 opts = setup_find_stream_info_opts(ic, codec_opts);
2750 orig_nb_streams = ic->nb_streams;
2752 err = avformat_find_stream_info(ic, opts);
2754 for (i = 0; i < orig_nb_streams; i++)
2755 av_dict_free(&opts[i]);
2759 av_log(NULL, AV_LOG_WARNING,
2760 "%s: could not find codec parameters\n", is->filename);
2766 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2768 if (seek_by_bytes < 0)
2769 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2771 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2773 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2774 window_title = av_asprintf("%s - %s", t->value, input_filename);
2776 /* if seeking requested, we execute it */
2777 if (start_time != AV_NOPTS_VALUE) {
2780 timestamp = start_time;
2781 /* add the stream start time */
2782 if (ic->start_time != AV_NOPTS_VALUE)
2783 timestamp += ic->start_time;
2784 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2786 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2787 is->filename, (double)timestamp / AV_TIME_BASE);
2791 is->realtime = is_realtime(ic);
2794 av_dump_format(ic, 0, is->filename, 0);
2796 for (i = 0; i < ic->nb_streams; i++) {
2797 AVStream *st = ic->streams[i];
2798 enum AVMediaType type = st->codecpar->codec_type;
2799 st->discard = AVDISCARD_ALL;
2800 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2801 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2804 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2805 if (wanted_stream_spec[i] && st_index[i] == -1) {
2806 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));
2807 st_index[i] = INT_MAX;
2812 st_index[AVMEDIA_TYPE_VIDEO] =
2813 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2814 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2816 st_index[AVMEDIA_TYPE_AUDIO] =
2817 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2818 st_index[AVMEDIA_TYPE_AUDIO],
2819 st_index[AVMEDIA_TYPE_VIDEO],
2821 if (!video_disable && !subtitle_disable)
2822 st_index[AVMEDIA_TYPE_SUBTITLE] =
2823 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2824 st_index[AVMEDIA_TYPE_SUBTITLE],
2825 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2826 st_index[AVMEDIA_TYPE_AUDIO] :
2827 st_index[AVMEDIA_TYPE_VIDEO]),
2830 is->show_mode = show_mode;
2831 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2832 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2833 AVCodecParameters *codecpar = st->codecpar;
2834 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2835 if (codecpar->width)
2836 set_default_window_size(codecpar->width, codecpar->height, sar);
2839 /* open the streams */
2840 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2841 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2845 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2846 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2848 if (is->show_mode == SHOW_MODE_NONE)
2849 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2851 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2852 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2855 if (is->video_stream < 0 && is->audio_stream < 0) {
2856 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2862 if (infinite_buffer < 0 && is->realtime)
2863 infinite_buffer = 1;
2866 if (is->abort_request)
2868 if (is->paused != is->last_paused) {
2869 is->last_paused = is->paused;
2871 is->read_pause_return = av_read_pause(ic);
2875 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2877 (!strcmp(ic->iformat->name, "rtsp") ||
2878 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2879 /* wait 10 ms to avoid trying to get another packet */
2886 int64_t seek_target = is->seek_pos;
2887 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2888 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2889 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2890 // of the seek_pos/seek_rel variables
2892 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2894 av_log(NULL, AV_LOG_ERROR,
2895 "%s: error while seeking\n", is->ic->filename);
2897 if (is->audio_stream >= 0) {
2898 packet_queue_flush(&is->audioq);
2899 packet_queue_put(&is->audioq, &flush_pkt);
2901 if (is->subtitle_stream >= 0) {
2902 packet_queue_flush(&is->subtitleq);
2903 packet_queue_put(&is->subtitleq, &flush_pkt);
2905 if (is->video_stream >= 0) {
2906 packet_queue_flush(&is->videoq);
2907 packet_queue_put(&is->videoq, &flush_pkt);
2909 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2910 set_clock(&is->extclk, NAN, 0);
2912 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2916 is->queue_attachments_req = 1;
2919 step_to_next_frame(is);
2921 if (is->queue_attachments_req) {
2922 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2924 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2926 packet_queue_put(&is->videoq, ©);
2927 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2929 is->queue_attachments_req = 0;
2932 /* if the queue are full, no need to read more */
2933 if (infinite_buffer<1 &&
2934 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2935 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2936 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2937 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2939 SDL_LockMutex(wait_mutex);
2940 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2941 SDL_UnlockMutex(wait_mutex);
2945 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2946 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2947 if (loop != 1 && (!loop || --loop)) {
2948 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2949 } else if (autoexit) {
2954 ret = av_read_frame(ic, pkt);
2956 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
2957 if (is->video_stream >= 0)
2958 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2959 if (is->audio_stream >= 0)
2960 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2961 if (is->subtitle_stream >= 0)
2962 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
2965 if (ic->pb && ic->pb->error)
2967 SDL_LockMutex(wait_mutex);
2968 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2969 SDL_UnlockMutex(wait_mutex);
2974 /* check if packet is in play range specified by user, then queue, otherwise discard */
2975 stream_start_time = ic->streams[pkt->stream_index]->start_time;
2976 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
2977 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2978 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
2979 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2980 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2981 <= ((double)duration / 1000000);
2982 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2983 packet_queue_put(&is->audioq, pkt);
2984 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2985 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
2986 packet_queue_put(&is->videoq, pkt);
2987 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2988 packet_queue_put(&is->subtitleq, pkt);
2990 av_packet_unref(pkt);
2997 avformat_close_input(&ic);
3002 event.type = FF_QUIT_EVENT;
3003 event.user.data1 = is;
3004 SDL_PushEvent(&event);
3006 SDL_DestroyMutex(wait_mutex);
3010 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3014 is = av_mallocz(sizeof(VideoState));
3017 is->filename = av_strdup(filename);
3020 is->iformat = iformat;
3024 /* start video display */
3025 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3027 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3029 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3032 if (packet_queue_init(&is->videoq) < 0 ||
3033 packet_queue_init(&is->audioq) < 0 ||
3034 packet_queue_init(&is->subtitleq) < 0)
3037 if (!(is->continue_read_thread = SDL_CreateCond())) {
3038 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3042 init_clock(&is->vidclk, &is->videoq.serial);
3043 init_clock(&is->audclk, &is->audioq.serial);
3044 init_clock(&is->extclk, &is->extclk.serial);
3045 is->audio_clock_serial = -1;
3046 if (startup_volume < 0)
3047 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3048 if (startup_volume > 100)
3049 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3050 startup_volume = av_clip(startup_volume, 0, 100);
3051 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3052 is->audio_volume = startup_volume;
3054 is->av_sync_type = av_sync_type;
3055 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3056 if (!is->read_tid) {
3057 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3065 static void stream_cycle_channel(VideoState *is, int codec_type)
3067 AVFormatContext *ic = is->ic;
3068 int start_index, stream_index;
3071 AVProgram *p = NULL;
3072 int nb_streams = is->ic->nb_streams;
3074 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3075 start_index = is->last_video_stream;
3076 old_index = is->video_stream;
3077 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3078 start_index = is->last_audio_stream;
3079 old_index = is->audio_stream;
3081 start_index = is->last_subtitle_stream;
3082 old_index = is->subtitle_stream;
3084 stream_index = start_index;
3086 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3087 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3089 nb_streams = p->nb_stream_indexes;
3090 for (start_index = 0; start_index < nb_streams; start_index++)
3091 if (p->stream_index[start_index] == stream_index)
3093 if (start_index == nb_streams)
3095 stream_index = start_index;
3100 if (++stream_index >= nb_streams)
3102 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3105 is->last_subtitle_stream = -1;
3108 if (start_index == -1)
3112 if (stream_index == start_index)
3114 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3115 if (st->codecpar->codec_type == codec_type) {
3116 /* check that parameters are OK */
3117 switch (codec_type) {
3118 case AVMEDIA_TYPE_AUDIO:
3119 if (st->codecpar->sample_rate != 0 &&
3120 st->codecpar->channels != 0)
3123 case AVMEDIA_TYPE_VIDEO:
3124 case AVMEDIA_TYPE_SUBTITLE:
3132 if (p && stream_index != -1)
3133 stream_index = p->stream_index[stream_index];
3134 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3135 av_get_media_type_string(codec_type),
3139 stream_component_close(is, old_index);
3140 stream_component_open(is, stream_index);
3144 static void toggle_full_screen(VideoState *is)
3146 is_full_screen = !is_full_screen;
3147 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3150 static void toggle_audio_display(VideoState *is)
3152 int next = is->show_mode;
3154 next = (next + 1) % SHOW_MODE_NB;
3155 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3156 if (is->show_mode != next) {
3157 is->force_refresh = 1;
3158 is->show_mode = next;
3162 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3163 double remaining_time = 0.0;
3165 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3166 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3170 if (remaining_time > 0.0)
3171 av_usleep((int64_t)(remaining_time * 1000000.0));
3172 remaining_time = REFRESH_RATE;
3173 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3174 video_refresh(is, &remaining_time);
3179 static void seek_chapter(VideoState *is, int incr)
3181 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3184 if (!is->ic->nb_chapters)
3187 /* find the current chapter */
3188 for (i = 0; i < is->ic->nb_chapters; i++) {
3189 AVChapter *ch = is->ic->chapters[i];
3190 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3198 if (i >= is->ic->nb_chapters)
3201 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3202 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3203 AV_TIME_BASE_Q), 0, 0);
3206 /* handle an event sent by the GUI */
3207 static void event_loop(VideoState *cur_stream)
3210 double incr, pos, frac;
3214 refresh_loop_wait_event(cur_stream, &event);
3215 switch (event.type) {
3217 if (exit_on_keydown) {
3218 do_exit(cur_stream);
3221 switch (event.key.keysym.sym) {
3224 do_exit(cur_stream);
3227 toggle_full_screen(cur_stream);
3228 cur_stream->force_refresh = 1;
3232 toggle_pause(cur_stream);
3235 toggle_mute(cur_stream);
3237 case SDLK_KP_MULTIPLY:
3239 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3241 case SDLK_KP_DIVIDE:
3243 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3245 case SDLK_s: // S: Step to next frame
3246 step_to_next_frame(cur_stream);
3249 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3252 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3255 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3256 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3257 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3260 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3264 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3265 if (++cur_stream->vfilter_idx >= nb_vfilters)
3266 cur_stream->vfilter_idx = 0;
3268 cur_stream->vfilter_idx = 0;
3269 toggle_audio_display(cur_stream);
3272 toggle_audio_display(cur_stream);
3276 if (cur_stream->ic->nb_chapters <= 1) {
3280 seek_chapter(cur_stream, 1);
3283 if (cur_stream->ic->nb_chapters <= 1) {
3287 seek_chapter(cur_stream, -1);
3301 if (seek_by_bytes) {
3303 if (pos < 0 && cur_stream->video_stream >= 0)
3304 pos = frame_queue_last_pos(&cur_stream->pictq);
3305 if (pos < 0 && cur_stream->audio_stream >= 0)
3306 pos = frame_queue_last_pos(&cur_stream->sampq);
3308 pos = avio_tell(cur_stream->ic->pb);
3309 if (cur_stream->ic->bit_rate)
3310 incr *= cur_stream->ic->bit_rate / 8.0;
3314 stream_seek(cur_stream, pos, incr, 1);
3316 pos = get_master_clock(cur_stream);
3318 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3320 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3321 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3322 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3329 case SDL_MOUSEBUTTONDOWN:
3330 if (exit_on_mousedown) {
3331 do_exit(cur_stream);
3334 if (event.button.button == SDL_BUTTON_LEFT) {
3335 static int64_t last_mouse_left_click = 0;
3336 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3337 toggle_full_screen(cur_stream);
3338 cur_stream->force_refresh = 1;
3339 last_mouse_left_click = 0;
3341 last_mouse_left_click = av_gettime_relative();
3344 case SDL_MOUSEMOTION:
3345 if (cursor_hidden) {
3349 cursor_last_shown = av_gettime_relative();
3350 if (event.type == SDL_MOUSEBUTTONDOWN) {
3351 if (event.button.button != SDL_BUTTON_RIGHT)
3355 if (!(event.motion.state & SDL_BUTTON_RMASK))
3359 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3360 uint64_t size = avio_size(cur_stream->ic->pb);
3361 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3365 int tns, thh, tmm, tss;
3366 tns = cur_stream->ic->duration / 1000000LL;
3368 tmm = (tns % 3600) / 60;
3370 frac = x / cur_stream->width;
3373 mm = (ns % 3600) / 60;
3375 av_log(NULL, AV_LOG_INFO,
3376 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3377 hh, mm, ss, thh, tmm, tss);
3378 ts = frac * cur_stream->ic->duration;
3379 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3380 ts += cur_stream->ic->start_time;
3381 stream_seek(cur_stream, ts, 0, 0);
3384 case SDL_WINDOWEVENT:
3385 switch (event.window.event) {
3386 case SDL_WINDOWEVENT_RESIZED:
3387 screen_width = cur_stream->width = event.window.data1;
3388 screen_height = cur_stream->height = event.window.data2;
3389 if (cur_stream->vis_texture) {
3390 SDL_DestroyTexture(cur_stream->vis_texture);
3391 cur_stream->vis_texture = NULL;
3393 case SDL_WINDOWEVENT_EXPOSED:
3394 cur_stream->force_refresh = 1;
3399 do_exit(cur_stream);
3407 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3409 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3410 return opt_default(NULL, "video_size", arg);
3413 static int opt_width(void *optctx, const char *opt, const char *arg)
3415 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3419 static int opt_height(void *optctx, const char *opt, const char *arg)
3421 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3425 static int opt_format(void *optctx, const char *opt, const char *arg)
3427 file_iformat = av_find_input_format(arg);
3428 if (!file_iformat) {
3429 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3430 return AVERROR(EINVAL);
3435 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3437 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3438 return opt_default(NULL, "pixel_format", arg);
3441 static int opt_sync(void *optctx, const char *opt, const char *arg)
3443 if (!strcmp(arg, "audio"))
3444 av_sync_type = AV_SYNC_AUDIO_MASTER;
3445 else if (!strcmp(arg, "video"))
3446 av_sync_type = AV_SYNC_VIDEO_MASTER;
3447 else if (!strcmp(arg, "ext"))
3448 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3450 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3456 static int opt_seek(void *optctx, const char *opt, const char *arg)
3458 start_time = parse_time_or_die(opt, arg, 1);
3462 static int opt_duration(void *optctx, const char *opt, const char *arg)
3464 duration = parse_time_or_die(opt, arg, 1);
3468 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3470 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3471 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3472 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3473 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3477 static void opt_input_file(void *optctx, const char *filename)
3479 if (input_filename) {
3480 av_log(NULL, AV_LOG_FATAL,
3481 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3482 filename, input_filename);
3485 if (!strcmp(filename, "-"))
3487 input_filename = filename;
3490 static int opt_codec(void *optctx, const char *opt, const char *arg)
3492 const char *spec = strchr(opt, ':');
3494 av_log(NULL, AV_LOG_ERROR,
3495 "No media specifier was specified in '%s' in option '%s'\n",
3497 return AVERROR(EINVAL);
3501 case 'a' : audio_codec_name = arg; break;
3502 case 's' : subtitle_codec_name = arg; break;
3503 case 'v' : video_codec_name = arg; break;
3505 av_log(NULL, AV_LOG_ERROR,
3506 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3507 return AVERROR(EINVAL);
3514 static const OptionDef options[] = {
3515 #include "cmdutils_common_opts.h"
3516 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3517 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3518 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3519 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3520 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3521 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3522 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3523 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3524 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3525 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3526 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3527 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3528 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3529 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3530 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3531 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3532 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3533 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3534 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3535 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3536 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3537 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3538 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3539 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3540 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3541 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3542 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3543 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3544 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3545 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3546 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3548 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3549 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3551 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3552 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3553 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3554 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3555 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3556 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3557 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3558 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3559 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3563 static void show_usage(void)
3565 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3566 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3567 av_log(NULL, AV_LOG_INFO, "\n");
3570 void show_help_default(const char *opt, const char *arg)
3572 av_log_set_callback(log_callback_help);
3574 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3575 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3577 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3578 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3579 #if !CONFIG_AVFILTER
3580 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3582 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3584 printf("\nWhile playing:\n"
3586 "f toggle full screen\n"
3589 "9, 0 decrease and increase volume respectively\n"
3590 "/, * decrease and increase volume respectively\n"
3591 "a cycle audio channel in the current program\n"
3592 "v cycle video channel\n"
3593 "t cycle subtitle channel in the current program\n"
3595 "w cycle video filters or show modes\n"
3596 "s activate frame-step mode\n"
3597 "left/right seek backward/forward 10 seconds\n"
3598 "down/up seek backward/forward 1 minute\n"
3599 "page down/page up seek backward/forward 10 minutes\n"
3600 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3601 "left double-click toggle full screen\n"
3605 static int lockmgr(void **mtx, enum AVLockOp op)
3608 case AV_LOCK_CREATE:
3609 *mtx = SDL_CreateMutex();
3611 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3615 case AV_LOCK_OBTAIN:
3616 return !!SDL_LockMutex(*mtx);
3617 case AV_LOCK_RELEASE:
3618 return !!SDL_UnlockMutex(*mtx);
3619 case AV_LOCK_DESTROY:
3620 SDL_DestroyMutex(*mtx);
3626 /* Called from the main */
3627 int main(int argc, char **argv)
3634 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3635 parse_loglevel(argc, argv, options);
3637 /* register all codecs, demux and protocols */
3639 avdevice_register_all();
3642 avfilter_register_all();
3645 avformat_network_init();
3649 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3650 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3652 show_banner(argc, argv, options);
3654 parse_options(NULL, argc, argv, options, opt_input_file);
3656 if (!input_filename) {
3658 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3659 av_log(NULL, AV_LOG_FATAL,
3660 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3664 if (display_disable) {
3667 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3669 flags &= ~SDL_INIT_AUDIO;
3671 /* Try to work around an occasional ALSA buffer underflow issue when the
3672 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3673 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3674 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3676 if (display_disable)
3677 flags &= ~SDL_INIT_VIDEO;
3678 if (SDL_Init (flags)) {
3679 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3680 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3684 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3685 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3687 if (av_lockmgr_register(lockmgr)) {
3688 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3692 av_init_packet(&flush_pkt);
3693 flush_pkt.data = (uint8_t *)&flush_pkt;
3695 is = stream_open(input_filename, file_iformat);
3697 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");