2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
110 static unsigned sws_flags = SWS_BICUBIC;
112 typedef struct MyAVPacketList {
114 struct MyAVPacketList *next;
118 typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
134 typedef struct AudioParams {
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
143 typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
148 int serial; /* clock is based on a packet with this serial */
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
170 typedef struct FrameQueue {
171 Frame queue[FRAME_QUEUE_SIZE];
184 AV_SYNC_AUDIO_MASTER, /* default choice */
185 AV_SYNC_VIDEO_MASTER,
186 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
189 typedef struct Decoder {
193 AVCodecContext *avctx;
197 SDL_cond *empty_queue_cond;
199 AVRational start_pts_tb;
201 AVRational next_pts_tb;
202 SDL_Thread *decoder_tid;
205 typedef struct VideoState {
206 SDL_Thread *read_tid;
207 AVInputFormat *iformat;
212 int queue_attachments_req;
217 int read_pause_return;
238 int audio_clock_serial;
239 double audio_diff_cum; /* used for AV difference average computation */
240 double audio_diff_avg_coef;
241 double audio_diff_threshold;
242 int audio_diff_avg_count;
245 int audio_hw_buf_size;
248 unsigned int audio_buf_size; /* in bytes */
249 unsigned int audio_buf1_size;
250 int audio_buf_index; /* in bytes */
251 int audio_write_buf_size;
254 struct AudioParams audio_src;
256 struct AudioParams audio_filter_src;
258 struct AudioParams audio_tgt;
259 struct SwrContext *swr_ctx;
260 int frame_drops_early;
261 int frame_drops_late;
264 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
266 int16_t sample_array[SAMPLE_ARRAY_SIZE];
267 int sample_array_index;
271 FFTSample *rdft_data;
273 double last_vis_time;
274 SDL_Texture *vis_texture;
275 SDL_Texture *sub_texture;
278 AVStream *subtitle_st;
279 PacketQueue subtitleq;
282 double frame_last_returned_time;
283 double frame_last_filter_delay;
287 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
288 struct SwsContext *img_convert_ctx;
289 struct SwsContext *sub_convert_ctx;
293 int width, height, xleft, ytop;
298 AVFilterContext *in_video_filter; // the first filter in the video chain
299 AVFilterContext *out_video_filter; // the last filter in the video chain
300 AVFilterContext *in_audio_filter; // the first filter in the audio chain
301 AVFilterContext *out_audio_filter; // the last filter in the audio chain
302 AVFilterGraph *agraph; // audio filter graph
305 int last_video_stream, last_audio_stream, last_subtitle_stream;
307 SDL_cond *continue_read_thread;
310 /* options specified by the user */
311 static AVInputFormat *file_iformat;
312 static const char *input_filename;
313 static const char *window_title;
314 static int default_width = 640;
315 static int default_height = 480;
316 static int screen_width = 0;
317 static int screen_height = 0;
318 static int audio_disable;
319 static int video_disable;
320 static int subtitle_disable;
321 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
322 static int seek_by_bytes = -1;
323 static int display_disable;
324 static int show_status = 1;
325 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
326 static int64_t start_time = AV_NOPTS_VALUE;
327 static int64_t duration = AV_NOPTS_VALUE;
329 static int genpts = 0;
330 static int lowres = 0;
331 static int decoder_reorder_pts = -1;
333 static int exit_on_keydown;
334 static int exit_on_mousedown;
336 static int framedrop = -1;
337 static int infinite_buffer = -1;
338 static enum ShowMode show_mode = SHOW_MODE_NONE;
339 static const char *audio_codec_name;
340 static const char *subtitle_codec_name;
341 static const char *video_codec_name;
342 double rdftspeed = 0.02;
343 static int64_t cursor_last_shown;
344 static int cursor_hidden = 0;
346 static const char **vfilters_list = NULL;
347 static int nb_vfilters = 0;
348 static char *afilters = NULL;
350 static int autorotate = 1;
352 /* current context */
353 static int is_full_screen;
354 static int64_t audio_callback_time;
356 static AVPacket flush_pkt;
358 #define FF_ALLOC_EVENT (SDL_USEREVENT)
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 void free_picture(Frame *vp);
395 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
397 MyAVPacketList *pkt1;
399 if (q->abort_request)
402 pkt1 = av_malloc(sizeof(MyAVPacketList));
407 if (pkt == &flush_pkt)
409 pkt1->serial = q->serial;
414 q->last_pkt->next = pkt1;
417 q->size += pkt1->pkt.size + sizeof(*pkt1);
418 q->duration += pkt1->pkt.duration;
419 /* XXX: should duplicate packet data in DV case */
420 SDL_CondSignal(q->cond);
424 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
428 SDL_LockMutex(q->mutex);
429 ret = packet_queue_put_private(q, pkt);
430 SDL_UnlockMutex(q->mutex);
432 if (pkt != &flush_pkt && ret < 0)
433 av_packet_unref(pkt);
438 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
440 AVPacket pkt1, *pkt = &pkt1;
444 pkt->stream_index = stream_index;
445 return packet_queue_put(q, pkt);
448 /* packet queue handling */
449 static int packet_queue_init(PacketQueue *q)
451 memset(q, 0, sizeof(PacketQueue));
452 q->mutex = SDL_CreateMutex();
454 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
455 return AVERROR(ENOMEM);
457 q->cond = SDL_CreateCond();
459 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
460 return AVERROR(ENOMEM);
462 q->abort_request = 1;
466 static void packet_queue_flush(PacketQueue *q)
468 MyAVPacketList *pkt, *pkt1;
470 SDL_LockMutex(q->mutex);
471 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
473 av_packet_unref(&pkt->pkt);
481 SDL_UnlockMutex(q->mutex);
484 static void packet_queue_destroy(PacketQueue *q)
486 packet_queue_flush(q);
487 SDL_DestroyMutex(q->mutex);
488 SDL_DestroyCond(q->cond);
491 static void packet_queue_abort(PacketQueue *q)
493 SDL_LockMutex(q->mutex);
495 q->abort_request = 1;
497 SDL_CondSignal(q->cond);
499 SDL_UnlockMutex(q->mutex);
502 static void packet_queue_start(PacketQueue *q)
504 SDL_LockMutex(q->mutex);
505 q->abort_request = 0;
506 packet_queue_put_private(q, &flush_pkt);
507 SDL_UnlockMutex(q->mutex);
510 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
511 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
513 MyAVPacketList *pkt1;
516 SDL_LockMutex(q->mutex);
519 if (q->abort_request) {
526 q->first_pkt = pkt1->next;
530 q->size -= pkt1->pkt.size + sizeof(*pkt1);
531 q->duration -= pkt1->pkt.duration;
534 *serial = pkt1->serial;
542 SDL_CondWait(q->cond, q->mutex);
545 SDL_UnlockMutex(q->mutex);
549 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
550 memset(d, 0, sizeof(Decoder));
553 d->empty_queue_cond = empty_queue_cond;
554 d->start_pts = AV_NOPTS_VALUE;
557 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
563 if (d->queue->abort_request)
566 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
569 if (d->queue->nb_packets == 0)
570 SDL_CondSignal(d->empty_queue_cond);
571 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
573 if (pkt.data == flush_pkt.data) {
574 avcodec_flush_buffers(d->avctx);
576 d->next_pts = d->start_pts;
577 d->next_pts_tb = d->start_pts_tb;
579 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
580 av_packet_unref(&d->pkt);
581 d->pkt_temp = d->pkt = pkt;
582 d->packet_pending = 1;
585 switch (d->avctx->codec_type) {
586 case AVMEDIA_TYPE_VIDEO:
587 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
589 if (decoder_reorder_pts == -1) {
590 frame->pts = av_frame_get_best_effort_timestamp(frame);
591 } else if (!decoder_reorder_pts) {
592 frame->pts = frame->pkt_dts;
596 case AVMEDIA_TYPE_AUDIO:
597 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
599 AVRational tb = (AVRational){1, frame->sample_rate};
600 if (frame->pts != AV_NOPTS_VALUE)
601 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
602 else if (d->next_pts != AV_NOPTS_VALUE)
603 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
604 if (frame->pts != AV_NOPTS_VALUE) {
605 d->next_pts = frame->pts + frame->nb_samples;
610 case AVMEDIA_TYPE_SUBTITLE:
611 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
616 d->packet_pending = 0;
619 d->pkt_temp.pts = AV_NOPTS_VALUE;
620 if (d->pkt_temp.data) {
621 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
622 ret = d->pkt_temp.size;
623 d->pkt_temp.data += ret;
624 d->pkt_temp.size -= ret;
625 if (d->pkt_temp.size <= 0)
626 d->packet_pending = 0;
629 d->packet_pending = 0;
630 d->finished = d->pkt_serial;
634 } while (!got_frame && !d->finished);
639 static void decoder_destroy(Decoder *d) {
640 av_packet_unref(&d->pkt);
641 avcodec_free_context(&d->avctx);
644 static void frame_queue_unref_item(Frame *vp)
646 av_frame_unref(vp->frame);
647 avsubtitle_free(&vp->sub);
650 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
653 memset(f, 0, sizeof(FrameQueue));
654 if (!(f->mutex = SDL_CreateMutex())) {
655 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
656 return AVERROR(ENOMEM);
658 if (!(f->cond = SDL_CreateCond())) {
659 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
660 return AVERROR(ENOMEM);
663 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
664 f->keep_last = !!keep_last;
665 for (i = 0; i < f->max_size; i++)
666 if (!(f->queue[i].frame = av_frame_alloc()))
667 return AVERROR(ENOMEM);
671 static void frame_queue_destory(FrameQueue *f)
674 for (i = 0; i < f->max_size; i++) {
675 Frame *vp = &f->queue[i];
676 frame_queue_unref_item(vp);
677 av_frame_free(&vp->frame);
680 SDL_DestroyMutex(f->mutex);
681 SDL_DestroyCond(f->cond);
684 static void frame_queue_signal(FrameQueue *f)
686 SDL_LockMutex(f->mutex);
687 SDL_CondSignal(f->cond);
688 SDL_UnlockMutex(f->mutex);
691 static Frame *frame_queue_peek(FrameQueue *f)
693 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
696 static Frame *frame_queue_peek_next(FrameQueue *f)
698 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
701 static Frame *frame_queue_peek_last(FrameQueue *f)
703 return &f->queue[f->rindex];
706 static Frame *frame_queue_peek_writable(FrameQueue *f)
708 /* wait until we have space to put a new frame */
709 SDL_LockMutex(f->mutex);
710 while (f->size >= f->max_size &&
711 !f->pktq->abort_request) {
712 SDL_CondWait(f->cond, f->mutex);
714 SDL_UnlockMutex(f->mutex);
716 if (f->pktq->abort_request)
719 return &f->queue[f->windex];
722 static Frame *frame_queue_peek_readable(FrameQueue *f)
724 /* wait until we have a readable a new frame */
725 SDL_LockMutex(f->mutex);
726 while (f->size - f->rindex_shown <= 0 &&
727 !f->pktq->abort_request) {
728 SDL_CondWait(f->cond, f->mutex);
730 SDL_UnlockMutex(f->mutex);
732 if (f->pktq->abort_request)
735 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
738 static void frame_queue_push(FrameQueue *f)
740 if (++f->windex == f->max_size)
742 SDL_LockMutex(f->mutex);
744 SDL_CondSignal(f->cond);
745 SDL_UnlockMutex(f->mutex);
748 static void frame_queue_next(FrameQueue *f)
750 if (f->keep_last && !f->rindex_shown) {
754 frame_queue_unref_item(&f->queue[f->rindex]);
755 if (++f->rindex == f->max_size)
757 SDL_LockMutex(f->mutex);
759 SDL_CondSignal(f->cond);
760 SDL_UnlockMutex(f->mutex);
763 /* return the number of undisplayed frames in the queue */
764 static int frame_queue_nb_remaining(FrameQueue *f)
766 return f->size - f->rindex_shown;
769 /* return last shown position */
770 static int64_t frame_queue_last_pos(FrameQueue *f)
772 Frame *fp = &f->queue[f->rindex];
773 if (f->rindex_shown && fp->serial == f->pktq->serial)
779 static void decoder_abort(Decoder *d, FrameQueue *fq)
781 packet_queue_abort(d->queue);
782 frame_queue_signal(fq);
783 SDL_WaitThread(d->decoder_tid, NULL);
784 d->decoder_tid = NULL;
785 packet_queue_flush(d->queue);
788 static inline void fill_rectangle(int x, int y, int w, int h)
796 SDL_RenderFillRect(renderer, &rect);
799 static void free_picture(Frame *vp)
802 SDL_DestroyTexture(vp->bmp);
807 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
811 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
814 SDL_DestroyTexture(*texture);
815 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
817 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
820 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
822 memset(pixels, 0, pitch * new_height);
823 SDL_UnlockTexture(*texture);
829 static void calculate_display_rect(SDL_Rect *rect,
830 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
831 int pic_width, int pic_height, AVRational pic_sar)
834 int width, height, x, y;
836 if (pic_sar.num == 0)
839 aspect_ratio = av_q2d(pic_sar);
841 if (aspect_ratio <= 0.0)
843 aspect_ratio *= (float)pic_width / (float)pic_height;
845 /* XXX: we suppose the screen has a 1.0 pixel ratio */
847 width = lrint(height * aspect_ratio) & ~1;
848 if (width > scr_width) {
850 height = lrint(width / aspect_ratio) & ~1;
852 x = (scr_width - width) / 2;
853 y = (scr_height - height) / 2;
854 rect->x = scr_xleft + x;
855 rect->y = scr_ytop + y;
856 rect->w = FFMAX(width, 1);
857 rect->h = FFMAX(height, 1);
860 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
862 switch (frame->format) {
863 case AV_PIX_FMT_YUV420P:
864 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
865 frame->data[1], frame->linesize[1],
866 frame->data[2], frame->linesize[2]);
868 case AV_PIX_FMT_BGRA:
869 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
872 /* This should only happen if we are not using avfilter... */
873 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
874 frame->width, frame->height, frame->format, frame->width, frame->height,
875 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
876 if (*img_convert_ctx != NULL) {
879 if (!SDL_LockTexture(tex, NULL, (void **)&pixels, &pitch)) {
880 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
881 0, frame->height, &pixels, &pitch);
882 SDL_UnlockTexture(tex);
885 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
893 static void video_image_display(VideoState *is)
899 vp = frame_queue_peek_last(&is->pictq);
901 if (is->subtitle_st) {
902 if (frame_queue_nb_remaining(&is->subpq) > 0) {
903 sp = frame_queue_peek(&is->subpq);
905 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
910 if (!sp->width || !sp->height) {
911 sp->width = vp->width;
912 sp->height = vp->height;
914 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
917 for (i = 0; i < sp->sub.num_rects; i++) {
918 AVSubtitleRect *sub_rect = sp->sub.rects[i];
920 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
921 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
922 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
923 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
925 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
926 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
927 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
928 0, NULL, NULL, NULL);
929 if (!is->sub_convert_ctx) {
930 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
933 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
934 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
935 0, sub_rect->h, &pixels, &pitch);
936 SDL_UnlockTexture(is->sub_texture);
946 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
949 if (upload_texture(vp->bmp, vp->frame, &is->img_convert_ctx) < 0)
954 SDL_RenderCopy(renderer, vp->bmp, NULL, &rect);
956 #if USE_ONEPASS_SUBTITLE_RENDER
957 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
960 double xratio = (double)rect.w / (double)sp->width;
961 double yratio = (double)rect.h / (double)sp->height;
962 for (i = 0; i < sp->sub.num_rects; i++) {
963 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
964 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
965 .y = rect.y + sub_rect->y * yratio,
966 .w = sub_rect->w * xratio,
967 .h = sub_rect->h * yratio};
968 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
975 static inline int compute_mod(int a, int b)
977 return a < 0 ? a%b + b : a%b;
980 static void video_audio_display(VideoState *s)
982 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
983 int ch, channels, h, h2;
985 int rdft_bits, nb_freq;
987 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
989 nb_freq = 1 << (rdft_bits - 1);
991 /* compute display index : center on currently output samples */
992 channels = s->audio_tgt.channels;
993 nb_display_channels = channels;
995 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
997 delay = s->audio_write_buf_size;
1000 /* to be more precise, we take into account the time spent since
1001 the last buffer computation */
1002 if (audio_callback_time) {
1003 time_diff = av_gettime_relative() - audio_callback_time;
1004 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1007 delay += 2 * data_used;
1008 if (delay < data_used)
1011 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1012 if (s->show_mode == SHOW_MODE_WAVES) {
1014 for (i = 0; i < 1000; i += channels) {
1015 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1016 int a = s->sample_array[idx];
1017 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1018 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1019 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1021 if (h < score && (b ^ c) < 0) {
1028 s->last_i_start = i_start;
1030 i_start = s->last_i_start;
1033 if (s->show_mode == SHOW_MODE_WAVES) {
1034 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1036 /* total height for one channel */
1037 h = s->height / nb_display_channels;
1038 /* graph height / 2 */
1040 for (ch = 0; ch < nb_display_channels; ch++) {
1042 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1043 for (x = 0; x < s->width; x++) {
1044 y = (s->sample_array[i] * h2) >> 15;
1051 fill_rectangle(s->xleft + x, ys, 1, y);
1053 if (i >= SAMPLE_ARRAY_SIZE)
1054 i -= SAMPLE_ARRAY_SIZE;
1058 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1060 for (ch = 1; ch < nb_display_channels; ch++) {
1061 y = s->ytop + ch * h;
1062 fill_rectangle(s->xleft, y, s->width, 1);
1065 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1068 nb_display_channels= FFMIN(nb_display_channels, 2);
1069 if (rdft_bits != s->rdft_bits) {
1070 av_rdft_end(s->rdft);
1071 av_free(s->rdft_data);
1072 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1073 s->rdft_bits = rdft_bits;
1074 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1076 if (!s->rdft || !s->rdft_data){
1077 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1078 s->show_mode = SHOW_MODE_WAVES;
1081 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1084 for (ch = 0; ch < nb_display_channels; ch++) {
1085 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1087 for (x = 0; x < 2 * nb_freq; x++) {
1088 double w = (x-nb_freq) * (1.0 / nb_freq);
1089 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1091 if (i >= SAMPLE_ARRAY_SIZE)
1092 i -= SAMPLE_ARRAY_SIZE;
1094 av_rdft_calc(s->rdft, data[ch]);
1096 /* Least efficient way to do this, we should of course
1097 * directly access it but it is more than fast enough. */
1098 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1100 pixels += pitch * s->height;
1101 for (y = 0; y < s->height; y++) {
1102 double w = 1 / sqrt(nb_freq);
1103 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
1104 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1109 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1111 SDL_UnlockTexture(s->vis_texture);
1113 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1117 if (s->xpos >= s->width)
1122 static void stream_component_close(VideoState *is, int stream_index)
1124 AVFormatContext *ic = is->ic;
1125 AVCodecParameters *codecpar;
1127 if (stream_index < 0 || stream_index >= ic->nb_streams)
1129 codecpar = ic->streams[stream_index]->codecpar;
1131 switch (codecpar->codec_type) {
1132 case AVMEDIA_TYPE_AUDIO:
1133 decoder_abort(&is->auddec, &is->sampq);
1135 decoder_destroy(&is->auddec);
1136 swr_free(&is->swr_ctx);
1137 av_freep(&is->audio_buf1);
1138 is->audio_buf1_size = 0;
1139 is->audio_buf = NULL;
1142 av_rdft_end(is->rdft);
1143 av_freep(&is->rdft_data);
1148 case AVMEDIA_TYPE_VIDEO:
1149 decoder_abort(&is->viddec, &is->pictq);
1150 decoder_destroy(&is->viddec);
1152 case AVMEDIA_TYPE_SUBTITLE:
1153 decoder_abort(&is->subdec, &is->subpq);
1154 decoder_destroy(&is->subdec);
1160 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1161 switch (codecpar->codec_type) {
1162 case AVMEDIA_TYPE_AUDIO:
1163 is->audio_st = NULL;
1164 is->audio_stream = -1;
1166 case AVMEDIA_TYPE_VIDEO:
1167 is->video_st = NULL;
1168 is->video_stream = -1;
1170 case AVMEDIA_TYPE_SUBTITLE:
1171 is->subtitle_st = NULL;
1172 is->subtitle_stream = -1;
1179 static void stream_close(VideoState *is)
1181 /* XXX: use a special url_shutdown call to abort parse cleanly */
1182 is->abort_request = 1;
1183 SDL_WaitThread(is->read_tid, NULL);
1185 /* close each stream */
1186 if (is->audio_stream >= 0)
1187 stream_component_close(is, is->audio_stream);
1188 if (is->video_stream >= 0)
1189 stream_component_close(is, is->video_stream);
1190 if (is->subtitle_stream >= 0)
1191 stream_component_close(is, is->subtitle_stream);
1193 avformat_close_input(&is->ic);
1195 packet_queue_destroy(&is->videoq);
1196 packet_queue_destroy(&is->audioq);
1197 packet_queue_destroy(&is->subtitleq);
1199 /* free all pictures */
1200 frame_queue_destory(&is->pictq);
1201 frame_queue_destory(&is->sampq);
1202 frame_queue_destory(&is->subpq);
1203 SDL_DestroyCond(is->continue_read_thread);
1204 sws_freeContext(is->img_convert_ctx);
1205 sws_freeContext(is->sub_convert_ctx);
1206 av_free(is->filename);
1207 if (is->vis_texture)
1208 SDL_DestroyTexture(is->vis_texture);
1209 if (is->sub_texture)
1210 SDL_DestroyTexture(is->sub_texture);
1214 static void do_exit(VideoState *is)
1220 SDL_DestroyRenderer(renderer);
1222 SDL_DestroyWindow(window);
1223 av_lockmgr_register(NULL);
1226 av_freep(&vfilters_list);
1228 avformat_network_deinit();
1232 av_log(NULL, AV_LOG_QUIET, "%s", "");
1236 static void sigterm_handler(int sig)
1241 static void set_default_window_size(int width, int height, AVRational sar)
1244 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1245 default_width = rect.w;
1246 default_height = rect.h;
1249 static int video_open(VideoState *is, Frame *vp)
1253 if (vp && vp->width)
1254 set_default_window_size(vp->width, vp->height, vp->sar);
1265 int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
1267 window_title = input_filename;
1269 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1270 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1271 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1273 SDL_RendererInfo info;
1274 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1276 if (!SDL_GetRendererInfo(renderer, &info))
1277 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1281 SDL_SetWindowSize(window, w, h);
1284 if (!window || !renderer) {
1285 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1295 /* display the current picture, if any */
1296 static void video_display(VideoState *is)
1299 video_open(is, NULL);
1301 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1302 SDL_RenderClear(renderer);
1303 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1304 video_audio_display(is);
1305 else if (is->video_st)
1306 video_image_display(is);
1307 SDL_RenderPresent(renderer);
1310 static double get_clock(Clock *c)
1312 if (*c->queue_serial != c->serial)
1317 double time = av_gettime_relative() / 1000000.0;
1318 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1322 static void set_clock_at(Clock *c, double pts, int serial, double time)
1325 c->last_updated = time;
1326 c->pts_drift = c->pts - time;
1330 static void set_clock(Clock *c, double pts, int serial)
1332 double time = av_gettime_relative() / 1000000.0;
1333 set_clock_at(c, pts, serial, time);
1336 static void set_clock_speed(Clock *c, double speed)
1338 set_clock(c, get_clock(c), c->serial);
1342 static void init_clock(Clock *c, int *queue_serial)
1346 c->queue_serial = queue_serial;
1347 set_clock(c, NAN, -1);
1350 static void sync_clock_to_slave(Clock *c, Clock *slave)
1352 double clock = get_clock(c);
1353 double slave_clock = get_clock(slave);
1354 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1355 set_clock(c, slave_clock, slave->serial);
1358 static int get_master_sync_type(VideoState *is) {
1359 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1361 return AV_SYNC_VIDEO_MASTER;
1363 return AV_SYNC_AUDIO_MASTER;
1364 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1366 return AV_SYNC_AUDIO_MASTER;
1368 return AV_SYNC_EXTERNAL_CLOCK;
1370 return AV_SYNC_EXTERNAL_CLOCK;
1374 /* get the current master clock value */
1375 static double get_master_clock(VideoState *is)
1379 switch (get_master_sync_type(is)) {
1380 case AV_SYNC_VIDEO_MASTER:
1381 val = get_clock(&is->vidclk);
1383 case AV_SYNC_AUDIO_MASTER:
1384 val = get_clock(&is->audclk);
1387 val = get_clock(&is->extclk);
1393 static void check_external_clock_speed(VideoState *is) {
1394 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1395 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1396 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1397 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1398 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1399 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1401 double speed = is->extclk.speed;
1403 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1407 /* seek in the stream */
1408 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1410 if (!is->seek_req) {
1413 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1415 is->seek_flags |= AVSEEK_FLAG_BYTE;
1417 SDL_CondSignal(is->continue_read_thread);
1421 /* pause or resume the video */
1422 static void stream_toggle_pause(VideoState *is)
1425 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1426 if (is->read_pause_return != AVERROR(ENOSYS)) {
1427 is->vidclk.paused = 0;
1429 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1431 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1432 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1435 static void toggle_pause(VideoState *is)
1437 stream_toggle_pause(is);
1441 static void toggle_mute(VideoState *is)
1443 is->muted = !is->muted;
1446 static void update_volume(VideoState *is, int sign, int step)
1448 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1451 static void step_to_next_frame(VideoState *is)
1453 /* if the stream is paused unpause it, then step */
1455 stream_toggle_pause(is);
1459 static double compute_target_delay(double delay, VideoState *is)
1461 double sync_threshold, diff = 0;
1463 /* update delay to follow master synchronisation source */
1464 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1465 /* if video is slave, we try to correct big delays by
1466 duplicating or deleting a frame */
1467 diff = get_clock(&is->vidclk) - get_master_clock(is);
1469 /* skip or repeat frame. We take into account the
1470 delay to compute the threshold. I still don't know
1471 if it is the best guess */
1472 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1473 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1474 if (diff <= -sync_threshold)
1475 delay = FFMAX(0, delay + diff);
1476 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1477 delay = delay + diff;
1478 else if (diff >= sync_threshold)
1483 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1489 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1490 if (vp->serial == nextvp->serial) {
1491 double duration = nextvp->pts - vp->pts;
1492 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1493 return vp->duration;
1501 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1502 /* update current video pts */
1503 set_clock(&is->vidclk, pts, serial);
1504 sync_clock_to_slave(&is->extclk, &is->vidclk);
1507 /* called to display each frame */
1508 static void video_refresh(void *opaque, double *remaining_time)
1510 VideoState *is = opaque;
1515 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1516 check_external_clock_speed(is);
1518 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1519 time = av_gettime_relative() / 1000000.0;
1520 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1522 is->last_vis_time = time;
1524 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1529 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1530 // nothing to do, no picture to display in the queue
1532 double last_duration, duration, delay;
1535 /* dequeue the picture */
1536 lastvp = frame_queue_peek_last(&is->pictq);
1537 vp = frame_queue_peek(&is->pictq);
1539 if (vp->serial != is->videoq.serial) {
1540 frame_queue_next(&is->pictq);
1544 if (lastvp->serial != vp->serial)
1545 is->frame_timer = av_gettime_relative() / 1000000.0;
1550 /* compute nominal last_duration */
1551 last_duration = vp_duration(is, lastvp, vp);
1552 delay = compute_target_delay(last_duration, is);
1554 time= av_gettime_relative()/1000000.0;
1555 if (time < is->frame_timer + delay) {
1556 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1560 is->frame_timer += delay;
1561 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1562 is->frame_timer = time;
1564 SDL_LockMutex(is->pictq.mutex);
1565 if (!isnan(vp->pts))
1566 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1567 SDL_UnlockMutex(is->pictq.mutex);
1569 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1570 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1571 duration = vp_duration(is, vp, nextvp);
1572 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1573 is->frame_drops_late++;
1574 frame_queue_next(&is->pictq);
1579 if (is->subtitle_st) {
1580 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1581 sp = frame_queue_peek(&is->subpq);
1583 if (frame_queue_nb_remaining(&is->subpq) > 1)
1584 sp2 = frame_queue_peek_next(&is->subpq);
1588 if (sp->serial != is->subtitleq.serial
1589 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1590 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1594 for (i = 0; i < sp->sub.num_rects; i++) {
1595 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1599 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1600 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1601 memset(pixels, 0, sub_rect->w << 2);
1602 SDL_UnlockTexture(is->sub_texture);
1606 frame_queue_next(&is->subpq);
1613 frame_queue_next(&is->pictq);
1614 is->force_refresh = 1;
1616 if (is->step && !is->paused)
1617 stream_toggle_pause(is);
1620 /* display picture */
1621 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1624 is->force_refresh = 0;
1626 static int64_t last_time;
1628 int aqsize, vqsize, sqsize;
1631 cur_time = av_gettime_relative();
1632 if (!last_time || (cur_time - last_time) >= 30000) {
1637 aqsize = is->audioq.size;
1639 vqsize = is->videoq.size;
1640 if (is->subtitle_st)
1641 sqsize = is->subtitleq.size;
1643 if (is->audio_st && is->video_st)
1644 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1645 else if (is->video_st)
1646 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1647 else if (is->audio_st)
1648 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1649 av_log(NULL, AV_LOG_INFO,
1650 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1651 get_master_clock(is),
1652 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1654 is->frame_drops_early + is->frame_drops_late,
1658 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1659 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1661 last_time = cur_time;
1666 /* allocate a picture (needs to do that in main thread to avoid
1667 potential locking problems */
1668 static void alloc_picture(VideoState *is)
1673 vp = &is->pictq.queue[is->pictq.windex];
1677 if (vp->format == AV_PIX_FMT_YUV420P)
1678 sdl_format = SDL_PIXELFORMAT_YV12;
1680 sdl_format = SDL_PIXELFORMAT_ARGB8888;
1682 if (realloc_texture(&vp->bmp, sdl_format, vp->width, vp->height, SDL_BLENDMODE_NONE, 0) < 0) {
1683 /* SDL allocates a buffer smaller than requested if the video
1684 * overlay hardware is unable to support the requested size. */
1685 av_log(NULL, AV_LOG_FATAL,
1686 "Error: the video system does not support an image\n"
1687 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1688 "to reduce the image size.\n", vp->width, vp->height );
1692 SDL_LockMutex(is->pictq.mutex);
1694 SDL_CondSignal(is->pictq.cond);
1695 SDL_UnlockMutex(is->pictq.mutex);
1698 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1702 #if defined(DEBUG_SYNC)
1703 printf("frame_type=%c pts=%0.3f\n",
1704 av_get_picture_type_char(src_frame->pict_type), pts);
1707 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1710 vp->sar = src_frame->sample_aspect_ratio;
1713 /* alloc or resize hardware picture buffer */
1714 if (!vp->bmp || !vp->allocated ||
1715 vp->width != src_frame->width ||
1716 vp->height != src_frame->height ||
1717 vp->format != src_frame->format) {
1721 vp->width = src_frame->width;
1722 vp->height = src_frame->height;
1723 vp->format = src_frame->format;
1725 /* the allocation must be done in the main thread to avoid
1726 locking problems. */
1727 event.type = FF_ALLOC_EVENT;
1728 event.user.data1 = is;
1729 SDL_PushEvent(&event);
1731 /* wait until the picture is allocated */
1732 SDL_LockMutex(is->pictq.mutex);
1733 while (!vp->allocated && !is->videoq.abort_request) {
1734 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1736 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1737 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, FF_ALLOC_EVENT, FF_ALLOC_EVENT) != 1) {
1738 while (!vp->allocated && !is->abort_request) {
1739 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1742 SDL_UnlockMutex(is->pictq.mutex);
1744 if (is->videoq.abort_request)
1748 /* if the frame is not skipped, then display it */
1751 vp->duration = duration;
1753 vp->serial = serial;
1755 av_frame_move_ref(vp->frame, src_frame);
1756 frame_queue_push(&is->pictq);
1761 static int get_video_frame(VideoState *is, AVFrame *frame)
1765 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1771 if (frame->pts != AV_NOPTS_VALUE)
1772 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1774 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1776 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1777 if (frame->pts != AV_NOPTS_VALUE) {
1778 double diff = dpts - get_master_clock(is);
1779 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1780 diff - is->frame_last_filter_delay < 0 &&
1781 is->viddec.pkt_serial == is->vidclk.serial &&
1782 is->videoq.nb_packets) {
1783 is->frame_drops_early++;
1784 av_frame_unref(frame);
1795 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1796 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1799 int nb_filters = graph->nb_filters;
1800 AVFilterInOut *outputs = NULL, *inputs = NULL;
1803 outputs = avfilter_inout_alloc();
1804 inputs = avfilter_inout_alloc();
1805 if (!outputs || !inputs) {
1806 ret = AVERROR(ENOMEM);
1810 outputs->name = av_strdup("in");
1811 outputs->filter_ctx = source_ctx;
1812 outputs->pad_idx = 0;
1813 outputs->next = NULL;
1815 inputs->name = av_strdup("out");
1816 inputs->filter_ctx = sink_ctx;
1817 inputs->pad_idx = 0;
1818 inputs->next = NULL;
1820 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1823 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1827 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1828 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1829 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1831 ret = avfilter_graph_config(graph, NULL);
1833 avfilter_inout_free(&outputs);
1834 avfilter_inout_free(&inputs);
1838 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1840 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1841 char sws_flags_str[512] = "";
1842 char buffersrc_args[256];
1844 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1845 AVCodecParameters *codecpar = is->video_st->codecpar;
1846 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1847 AVDictionaryEntry *e = NULL;
1849 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1850 if (!strcmp(e->key, "sws_flags")) {
1851 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1853 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1855 if (strlen(sws_flags_str))
1856 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1858 graph->scale_sws_opts = av_strdup(sws_flags_str);
1860 snprintf(buffersrc_args, sizeof(buffersrc_args),
1861 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1862 frame->width, frame->height, frame->format,
1863 is->video_st->time_base.num, is->video_st->time_base.den,
1864 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1865 if (fr.num && fr.den)
1866 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1868 if ((ret = avfilter_graph_create_filter(&filt_src,
1869 avfilter_get_by_name("buffer"),
1870 "ffplay_buffer", buffersrc_args, NULL,
1874 ret = avfilter_graph_create_filter(&filt_out,
1875 avfilter_get_by_name("buffersink"),
1876 "ffplay_buffersink", NULL, NULL, graph);
1880 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1883 last_filter = filt_out;
1885 /* Note: this macro adds a filter before the lastly added filter, so the
1886 * processing order of the filters is in reverse */
1887 #define INSERT_FILT(name, arg) do { \
1888 AVFilterContext *filt_ctx; \
1890 ret = avfilter_graph_create_filter(&filt_ctx, \
1891 avfilter_get_by_name(name), \
1892 "ffplay_" name, arg, NULL, graph); \
1896 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1900 last_filter = filt_ctx; \
1904 double theta = get_rotation(is->video_st);
1906 if (fabs(theta - 90) < 1.0) {
1907 INSERT_FILT("transpose", "clock");
1908 } else if (fabs(theta - 180) < 1.0) {
1909 INSERT_FILT("hflip", NULL);
1910 INSERT_FILT("vflip", NULL);
1911 } else if (fabs(theta - 270) < 1.0) {
1912 INSERT_FILT("transpose", "cclock");
1913 } else if (fabs(theta) > 1.0) {
1914 char rotate_buf[64];
1915 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1916 INSERT_FILT("rotate", rotate_buf);
1920 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1923 is->in_video_filter = filt_src;
1924 is->out_video_filter = filt_out;
1930 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1932 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1933 int sample_rates[2] = { 0, -1 };
1934 int64_t channel_layouts[2] = { 0, -1 };
1935 int channels[2] = { 0, -1 };
1936 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1937 char aresample_swr_opts[512] = "";
1938 AVDictionaryEntry *e = NULL;
1939 char asrc_args[256];
1942 avfilter_graph_free(&is->agraph);
1943 if (!(is->agraph = avfilter_graph_alloc()))
1944 return AVERROR(ENOMEM);
1946 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1947 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1948 if (strlen(aresample_swr_opts))
1949 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1950 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1952 ret = snprintf(asrc_args, sizeof(asrc_args),
1953 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1954 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1955 is->audio_filter_src.channels,
1956 1, is->audio_filter_src.freq);
1957 if (is->audio_filter_src.channel_layout)
1958 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1959 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1961 ret = avfilter_graph_create_filter(&filt_asrc,
1962 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1963 asrc_args, NULL, is->agraph);
1968 ret = avfilter_graph_create_filter(&filt_asink,
1969 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1970 NULL, NULL, is->agraph);
1974 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1976 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1979 if (force_output_format) {
1980 channel_layouts[0] = is->audio_tgt.channel_layout;
1981 channels [0] = is->audio_tgt.channels;
1982 sample_rates [0] = is->audio_tgt.freq;
1983 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1985 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1987 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1989 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1994 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1997 is->in_audio_filter = filt_asrc;
1998 is->out_audio_filter = filt_asink;
2002 avfilter_graph_free(&is->agraph);
2005 #endif /* CONFIG_AVFILTER */
2007 static int audio_thread(void *arg)
2009 VideoState *is = arg;
2010 AVFrame *frame = av_frame_alloc();
2013 int last_serial = -1;
2014 int64_t dec_channel_layout;
2022 return AVERROR(ENOMEM);
2025 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2029 tb = (AVRational){1, frame->sample_rate};
2032 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2035 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2036 frame->format, av_frame_get_channels(frame)) ||
2037 is->audio_filter_src.channel_layout != dec_channel_layout ||
2038 is->audio_filter_src.freq != frame->sample_rate ||
2039 is->auddec.pkt_serial != last_serial;
2042 char buf1[1024], buf2[1024];
2043 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2044 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2045 av_log(NULL, AV_LOG_DEBUG,
2046 "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",
2047 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2048 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2050 is->audio_filter_src.fmt = frame->format;
2051 is->audio_filter_src.channels = av_frame_get_channels(frame);
2052 is->audio_filter_src.channel_layout = dec_channel_layout;
2053 is->audio_filter_src.freq = frame->sample_rate;
2054 last_serial = is->auddec.pkt_serial;
2056 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2060 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2063 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2064 tb = is->out_audio_filter->inputs[0]->time_base;
2066 if (!(af = frame_queue_peek_writable(&is->sampq)))
2069 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2070 af->pos = av_frame_get_pkt_pos(frame);
2071 af->serial = is->auddec.pkt_serial;
2072 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2074 av_frame_move_ref(af->frame, frame);
2075 frame_queue_push(&is->sampq);
2078 if (is->audioq.serial != is->auddec.pkt_serial)
2081 if (ret == AVERROR_EOF)
2082 is->auddec.finished = is->auddec.pkt_serial;
2085 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2088 avfilter_graph_free(&is->agraph);
2090 av_frame_free(&frame);
2094 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2096 packet_queue_start(d->queue);
2097 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2098 if (!d->decoder_tid) {
2099 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2100 return AVERROR(ENOMEM);
2105 static int video_thread(void *arg)
2107 VideoState *is = arg;
2108 AVFrame *frame = av_frame_alloc();
2112 AVRational tb = is->video_st->time_base;
2113 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2116 AVFilterGraph *graph = avfilter_graph_alloc();
2117 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2120 enum AVPixelFormat last_format = -2;
2121 int last_serial = -1;
2122 int last_vfilter_idx = 0;
2124 av_frame_free(&frame);
2125 return AVERROR(ENOMEM);
2132 avfilter_graph_free(&graph);
2134 return AVERROR(ENOMEM);
2138 ret = get_video_frame(is, frame);
2145 if ( last_w != frame->width
2146 || last_h != frame->height
2147 || last_format != frame->format
2148 || last_serial != is->viddec.pkt_serial
2149 || last_vfilter_idx != is->vfilter_idx) {
2150 av_log(NULL, AV_LOG_DEBUG,
2151 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2153 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2154 frame->width, frame->height,
2155 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2156 avfilter_graph_free(&graph);
2157 graph = avfilter_graph_alloc();
2158 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2160 event.type = FF_QUIT_EVENT;
2161 event.user.data1 = is;
2162 SDL_PushEvent(&event);
2165 filt_in = is->in_video_filter;
2166 filt_out = is->out_video_filter;
2167 last_w = frame->width;
2168 last_h = frame->height;
2169 last_format = frame->format;
2170 last_serial = is->viddec.pkt_serial;
2171 last_vfilter_idx = is->vfilter_idx;
2172 frame_rate = filt_out->inputs[0]->frame_rate;
2175 ret = av_buffersrc_add_frame(filt_in, frame);
2180 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2182 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2184 if (ret == AVERROR_EOF)
2185 is->viddec.finished = is->viddec.pkt_serial;
2190 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2191 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2192 is->frame_last_filter_delay = 0;
2193 tb = filt_out->inputs[0]->time_base;
2195 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2196 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2197 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2198 av_frame_unref(frame);
2208 avfilter_graph_free(&graph);
2210 av_frame_free(&frame);
2214 static int subtitle_thread(void *arg)
2216 VideoState *is = arg;
2222 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2225 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2230 if (got_subtitle && sp->sub.format == 0) {
2231 if (sp->sub.pts != AV_NOPTS_VALUE)
2232 pts = sp->sub.pts / (double)AV_TIME_BASE;
2234 sp->serial = is->subdec.pkt_serial;
2235 sp->width = is->subdec.avctx->width;
2236 sp->height = is->subdec.avctx->height;
2239 /* now we can update the picture count */
2240 frame_queue_push(&is->subpq);
2241 } else if (got_subtitle) {
2242 avsubtitle_free(&sp->sub);
2248 /* copy samples for viewing in editor window */
2249 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2253 size = samples_size / sizeof(short);
2255 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2258 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2260 is->sample_array_index += len;
2261 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2262 is->sample_array_index = 0;
2267 /* return the wanted number of samples to get better sync if sync_type is video
2268 * or external master clock */
2269 static int synchronize_audio(VideoState *is, int nb_samples)
2271 int wanted_nb_samples = nb_samples;
2273 /* if not master, then we try to remove or add samples to correct the clock */
2274 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2275 double diff, avg_diff;
2276 int min_nb_samples, max_nb_samples;
2278 diff = get_clock(&is->audclk) - get_master_clock(is);
2280 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2281 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2282 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2283 /* not enough measures to have a correct estimate */
2284 is->audio_diff_avg_count++;
2286 /* estimate the A-V difference */
2287 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2289 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2290 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2291 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2292 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2293 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2295 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2296 diff, avg_diff, wanted_nb_samples - nb_samples,
2297 is->audio_clock, is->audio_diff_threshold);
2300 /* too big difference : may be initial PTS errors, so
2302 is->audio_diff_avg_count = 0;
2303 is->audio_diff_cum = 0;
2307 return wanted_nb_samples;
2311 * Decode one audio frame and return its uncompressed size.
2313 * The processed audio frame is decoded, converted if required, and
2314 * stored in is->audio_buf, with size in bytes given by the return
2317 static int audio_decode_frame(VideoState *is)
2319 int data_size, resampled_data_size;
2320 int64_t dec_channel_layout;
2321 av_unused double audio_clock0;
2322 int wanted_nb_samples;
2330 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2331 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2336 if (!(af = frame_queue_peek_readable(&is->sampq)))
2338 frame_queue_next(&is->sampq);
2339 } while (af->serial != is->audioq.serial);
2341 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2342 af->frame->nb_samples,
2343 af->frame->format, 1);
2345 dec_channel_layout =
2346 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2347 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2348 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2350 if (af->frame->format != is->audio_src.fmt ||
2351 dec_channel_layout != is->audio_src.channel_layout ||
2352 af->frame->sample_rate != is->audio_src.freq ||
2353 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2354 swr_free(&is->swr_ctx);
2355 is->swr_ctx = swr_alloc_set_opts(NULL,
2356 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2357 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2359 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2360 av_log(NULL, AV_LOG_ERROR,
2361 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2362 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2363 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2364 swr_free(&is->swr_ctx);
2367 is->audio_src.channel_layout = dec_channel_layout;
2368 is->audio_src.channels = av_frame_get_channels(af->frame);
2369 is->audio_src.freq = af->frame->sample_rate;
2370 is->audio_src.fmt = af->frame->format;
2374 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2375 uint8_t **out = &is->audio_buf1;
2376 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2377 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2380 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2383 if (wanted_nb_samples != af->frame->nb_samples) {
2384 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2385 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2386 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2390 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2391 if (!is->audio_buf1)
2392 return AVERROR(ENOMEM);
2393 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2395 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2398 if (len2 == out_count) {
2399 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2400 if (swr_init(is->swr_ctx) < 0)
2401 swr_free(&is->swr_ctx);
2403 is->audio_buf = is->audio_buf1;
2404 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2406 is->audio_buf = af->frame->data[0];
2407 resampled_data_size = data_size;
2410 audio_clock0 = is->audio_clock;
2411 /* update the audio clock with the pts */
2412 if (!isnan(af->pts))
2413 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2415 is->audio_clock = NAN;
2416 is->audio_clock_serial = af->serial;
2419 static double last_clock;
2420 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2421 is->audio_clock - last_clock,
2422 is->audio_clock, audio_clock0);
2423 last_clock = is->audio_clock;
2426 return resampled_data_size;
2429 /* prepare a new audio buffer */
2430 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2432 VideoState *is = opaque;
2433 int audio_size, len1;
2435 audio_callback_time = av_gettime_relative();
2438 if (is->audio_buf_index >= is->audio_buf_size) {
2439 audio_size = audio_decode_frame(is);
2440 if (audio_size < 0) {
2441 /* if error, just output silence */
2442 is->audio_buf = NULL;
2443 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2445 if (is->show_mode != SHOW_MODE_VIDEO)
2446 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2447 is->audio_buf_size = audio_size;
2449 is->audio_buf_index = 0;
2451 len1 = is->audio_buf_size - is->audio_buf_index;
2454 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2455 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2457 memset(stream, 0, len1);
2458 if (!is->muted && is->audio_buf)
2459 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2463 is->audio_buf_index += len1;
2465 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2466 /* Let's assume the audio driver that is used by SDL has two periods. */
2467 if (!isnan(is->audio_clock)) {
2468 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);
2469 sync_clock_to_slave(&is->extclk, &is->audclk);
2473 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2475 SDL_AudioSpec wanted_spec, spec;
2477 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2478 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2479 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2481 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2483 wanted_nb_channels = atoi(env);
2484 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2486 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2487 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2488 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2490 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2491 wanted_spec.channels = wanted_nb_channels;
2492 wanted_spec.freq = wanted_sample_rate;
2493 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2494 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2497 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2498 next_sample_rate_idx--;
2499 wanted_spec.format = AUDIO_S16SYS;
2500 wanted_spec.silence = 0;
2501 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2502 wanted_spec.callback = sdl_audio_callback;
2503 wanted_spec.userdata = opaque;
2504 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2505 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2506 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2507 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2508 if (!wanted_spec.channels) {
2509 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2510 wanted_spec.channels = wanted_nb_channels;
2511 if (!wanted_spec.freq) {
2512 av_log(NULL, AV_LOG_ERROR,
2513 "No more combinations to try, audio open failed\n");
2517 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2519 if (spec.format != AUDIO_S16SYS) {
2520 av_log(NULL, AV_LOG_ERROR,
2521 "SDL advised audio format %d is not supported!\n", spec.format);
2524 if (spec.channels != wanted_spec.channels) {
2525 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2526 if (!wanted_channel_layout) {
2527 av_log(NULL, AV_LOG_ERROR,
2528 "SDL advised channel count %d is not supported!\n", spec.channels);
2533 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2534 audio_hw_params->freq = spec.freq;
2535 audio_hw_params->channel_layout = wanted_channel_layout;
2536 audio_hw_params->channels = spec.channels;
2537 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2538 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);
2539 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2540 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2546 /* open a given stream. Return 0 if OK */
2547 static int stream_component_open(VideoState *is, int stream_index)
2549 AVFormatContext *ic = is->ic;
2550 AVCodecContext *avctx;
2552 const char *forced_codec_name = NULL;
2553 AVDictionary *opts = NULL;
2554 AVDictionaryEntry *t = NULL;
2555 int sample_rate, nb_channels;
2556 int64_t channel_layout;
2558 int stream_lowres = lowres;
2560 if (stream_index < 0 || stream_index >= ic->nb_streams)
2563 avctx = avcodec_alloc_context3(NULL);
2565 return AVERROR(ENOMEM);
2567 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2570 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2572 codec = avcodec_find_decoder(avctx->codec_id);
2574 switch(avctx->codec_type){
2575 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2576 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2577 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2579 if (forced_codec_name)
2580 codec = avcodec_find_decoder_by_name(forced_codec_name);
2582 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2583 "No codec could be found with name '%s'\n", forced_codec_name);
2584 else av_log(NULL, AV_LOG_WARNING,
2585 "No codec could be found with id %d\n", avctx->codec_id);
2586 ret = AVERROR(EINVAL);
2590 avctx->codec_id = codec->id;
2591 if(stream_lowres > av_codec_get_max_lowres(codec)){
2592 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2593 av_codec_get_max_lowres(codec));
2594 stream_lowres = av_codec_get_max_lowres(codec);
2596 av_codec_set_lowres(avctx, stream_lowres);
2599 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2602 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2604 if(codec->capabilities & AV_CODEC_CAP_DR1)
2605 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2608 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2609 if (!av_dict_get(opts, "threads", NULL, 0))
2610 av_dict_set(&opts, "threads", "auto", 0);
2612 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2613 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2614 av_dict_set(&opts, "refcounted_frames", "1", 0);
2615 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2618 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2619 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2620 ret = AVERROR_OPTION_NOT_FOUND;
2625 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2626 switch (avctx->codec_type) {
2627 case AVMEDIA_TYPE_AUDIO:
2632 is->audio_filter_src.freq = avctx->sample_rate;
2633 is->audio_filter_src.channels = avctx->channels;
2634 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2635 is->audio_filter_src.fmt = avctx->sample_fmt;
2636 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2638 link = is->out_audio_filter->inputs[0];
2639 sample_rate = link->sample_rate;
2640 nb_channels = avfilter_link_get_channels(link);
2641 channel_layout = link->channel_layout;
2644 sample_rate = avctx->sample_rate;
2645 nb_channels = avctx->channels;
2646 channel_layout = avctx->channel_layout;
2649 /* prepare audio output */
2650 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2652 is->audio_hw_buf_size = ret;
2653 is->audio_src = is->audio_tgt;
2654 is->audio_buf_size = 0;
2655 is->audio_buf_index = 0;
2657 /* init averaging filter */
2658 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2659 is->audio_diff_avg_count = 0;
2660 /* since we do not have a precise anough audio FIFO fullness,
2661 we correct audio sync only if larger than this threshold */
2662 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2664 is->audio_stream = stream_index;
2665 is->audio_st = ic->streams[stream_index];
2667 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2668 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2669 is->auddec.start_pts = is->audio_st->start_time;
2670 is->auddec.start_pts_tb = is->audio_st->time_base;
2672 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2676 case AVMEDIA_TYPE_VIDEO:
2677 is->video_stream = stream_index;
2678 is->video_st = ic->streams[stream_index];
2680 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2681 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2683 is->queue_attachments_req = 1;
2685 case AVMEDIA_TYPE_SUBTITLE:
2686 is->subtitle_stream = stream_index;
2687 is->subtitle_st = ic->streams[stream_index];
2689 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2690 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2699 avcodec_free_context(&avctx);
2701 av_dict_free(&opts);
2706 static int decode_interrupt_cb(void *ctx)
2708 VideoState *is = ctx;
2709 return is->abort_request;
2712 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2713 return stream_id < 0 ||
2714 queue->abort_request ||
2715 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2716 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2719 static int is_realtime(AVFormatContext *s)
2721 if( !strcmp(s->iformat->name, "rtp")
2722 || !strcmp(s->iformat->name, "rtsp")
2723 || !strcmp(s->iformat->name, "sdp")
2727 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2728 || !strncmp(s->filename, "udp:", 4)
2735 /* this thread gets the stream from the disk or the network */
2736 static int read_thread(void *arg)
2738 VideoState *is = arg;
2739 AVFormatContext *ic = NULL;
2741 int st_index[AVMEDIA_TYPE_NB];
2742 AVPacket pkt1, *pkt = &pkt1;
2743 int64_t stream_start_time;
2744 int pkt_in_play_range = 0;
2745 AVDictionaryEntry *t;
2746 AVDictionary **opts;
2747 int orig_nb_streams;
2748 SDL_mutex *wait_mutex = SDL_CreateMutex();
2749 int scan_all_pmts_set = 0;
2753 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2754 ret = AVERROR(ENOMEM);
2758 memset(st_index, -1, sizeof(st_index));
2759 is->last_video_stream = is->video_stream = -1;
2760 is->last_audio_stream = is->audio_stream = -1;
2761 is->last_subtitle_stream = is->subtitle_stream = -1;
2764 ic = avformat_alloc_context();
2766 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2767 ret = AVERROR(ENOMEM);
2770 ic->interrupt_callback.callback = decode_interrupt_cb;
2771 ic->interrupt_callback.opaque = is;
2772 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2773 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2774 scan_all_pmts_set = 1;
2776 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2778 print_error(is->filename, err);
2782 if (scan_all_pmts_set)
2783 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2785 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2786 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2787 ret = AVERROR_OPTION_NOT_FOUND;
2793 ic->flags |= AVFMT_FLAG_GENPTS;
2795 av_format_inject_global_side_data(ic);
2797 opts = setup_find_stream_info_opts(ic, codec_opts);
2798 orig_nb_streams = ic->nb_streams;
2800 err = avformat_find_stream_info(ic, opts);
2802 for (i = 0; i < orig_nb_streams; i++)
2803 av_dict_free(&opts[i]);
2807 av_log(NULL, AV_LOG_WARNING,
2808 "%s: could not find codec parameters\n", is->filename);
2814 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2816 if (seek_by_bytes < 0)
2817 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2819 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2821 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2822 window_title = av_asprintf("%s - %s", t->value, input_filename);
2824 /* if seeking requested, we execute it */
2825 if (start_time != AV_NOPTS_VALUE) {
2828 timestamp = start_time;
2829 /* add the stream start time */
2830 if (ic->start_time != AV_NOPTS_VALUE)
2831 timestamp += ic->start_time;
2832 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2834 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2835 is->filename, (double)timestamp / AV_TIME_BASE);
2839 is->realtime = is_realtime(ic);
2842 av_dump_format(ic, 0, is->filename, 0);
2844 for (i = 0; i < ic->nb_streams; i++) {
2845 AVStream *st = ic->streams[i];
2846 enum AVMediaType type = st->codecpar->codec_type;
2847 st->discard = AVDISCARD_ALL;
2848 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2849 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2852 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2853 if (wanted_stream_spec[i] && st_index[i] == -1) {
2854 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));
2855 st_index[i] = INT_MAX;
2860 st_index[AVMEDIA_TYPE_VIDEO] =
2861 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2862 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2864 st_index[AVMEDIA_TYPE_AUDIO] =
2865 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2866 st_index[AVMEDIA_TYPE_AUDIO],
2867 st_index[AVMEDIA_TYPE_VIDEO],
2869 if (!video_disable && !subtitle_disable)
2870 st_index[AVMEDIA_TYPE_SUBTITLE] =
2871 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2872 st_index[AVMEDIA_TYPE_SUBTITLE],
2873 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2874 st_index[AVMEDIA_TYPE_AUDIO] :
2875 st_index[AVMEDIA_TYPE_VIDEO]),
2878 is->show_mode = show_mode;
2879 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2880 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2881 AVCodecParameters *codecpar = st->codecpar;
2882 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2883 if (codecpar->width)
2884 set_default_window_size(codecpar->width, codecpar->height, sar);
2887 /* open the streams */
2888 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2889 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2893 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2894 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2896 if (is->show_mode == SHOW_MODE_NONE)
2897 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2899 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2900 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2903 if (is->video_stream < 0 && is->audio_stream < 0) {
2904 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2910 if (infinite_buffer < 0 && is->realtime)
2911 infinite_buffer = 1;
2914 if (is->abort_request)
2916 if (is->paused != is->last_paused) {
2917 is->last_paused = is->paused;
2919 is->read_pause_return = av_read_pause(ic);
2923 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2925 (!strcmp(ic->iformat->name, "rtsp") ||
2926 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2927 /* wait 10 ms to avoid trying to get another packet */
2934 int64_t seek_target = is->seek_pos;
2935 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2936 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2937 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2938 // of the seek_pos/seek_rel variables
2940 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2942 av_log(NULL, AV_LOG_ERROR,
2943 "%s: error while seeking\n", is->ic->filename);
2945 if (is->audio_stream >= 0) {
2946 packet_queue_flush(&is->audioq);
2947 packet_queue_put(&is->audioq, &flush_pkt);
2949 if (is->subtitle_stream >= 0) {
2950 packet_queue_flush(&is->subtitleq);
2951 packet_queue_put(&is->subtitleq, &flush_pkt);
2953 if (is->video_stream >= 0) {
2954 packet_queue_flush(&is->videoq);
2955 packet_queue_put(&is->videoq, &flush_pkt);
2957 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2958 set_clock(&is->extclk, NAN, 0);
2960 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2964 is->queue_attachments_req = 1;
2967 step_to_next_frame(is);
2969 if (is->queue_attachments_req) {
2970 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2972 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2974 packet_queue_put(&is->videoq, ©);
2975 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2977 is->queue_attachments_req = 0;
2980 /* if the queue are full, no need to read more */
2981 if (infinite_buffer<1 &&
2982 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2983 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2984 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2985 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2987 SDL_LockMutex(wait_mutex);
2988 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2989 SDL_UnlockMutex(wait_mutex);
2993 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2994 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2995 if (loop != 1 && (!loop || --loop)) {
2996 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2997 } else if (autoexit) {
3002 ret = av_read_frame(ic, pkt);
3004 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3005 if (is->video_stream >= 0)
3006 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3007 if (is->audio_stream >= 0)
3008 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3009 if (is->subtitle_stream >= 0)
3010 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3013 if (ic->pb && ic->pb->error)
3015 SDL_LockMutex(wait_mutex);
3016 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3017 SDL_UnlockMutex(wait_mutex);
3022 /* check if packet is in play range specified by user, then queue, otherwise discard */
3023 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3024 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3025 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3026 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3027 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3028 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3029 <= ((double)duration / 1000000);
3030 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3031 packet_queue_put(&is->audioq, pkt);
3032 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3033 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3034 packet_queue_put(&is->videoq, pkt);
3035 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3036 packet_queue_put(&is->subtitleq, pkt);
3038 av_packet_unref(pkt);
3045 avformat_close_input(&ic);
3050 event.type = FF_QUIT_EVENT;
3051 event.user.data1 = is;
3052 SDL_PushEvent(&event);
3054 SDL_DestroyMutex(wait_mutex);
3058 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3062 is = av_mallocz(sizeof(VideoState));
3065 is->filename = av_strdup(filename);
3068 is->iformat = iformat;
3072 /* start video display */
3073 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3075 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3077 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3080 if (packet_queue_init(&is->videoq) < 0 ||
3081 packet_queue_init(&is->audioq) < 0 ||
3082 packet_queue_init(&is->subtitleq) < 0)
3085 if (!(is->continue_read_thread = SDL_CreateCond())) {
3086 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3090 init_clock(&is->vidclk, &is->videoq.serial);
3091 init_clock(&is->audclk, &is->audioq.serial);
3092 init_clock(&is->extclk, &is->extclk.serial);
3093 is->audio_clock_serial = -1;
3094 is->audio_volume = SDL_MIX_MAXVOLUME;
3096 is->av_sync_type = av_sync_type;
3097 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3098 if (!is->read_tid) {
3099 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3107 static void stream_cycle_channel(VideoState *is, int codec_type)
3109 AVFormatContext *ic = is->ic;
3110 int start_index, stream_index;
3113 AVProgram *p = NULL;
3114 int nb_streams = is->ic->nb_streams;
3116 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3117 start_index = is->last_video_stream;
3118 old_index = is->video_stream;
3119 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3120 start_index = is->last_audio_stream;
3121 old_index = is->audio_stream;
3123 start_index = is->last_subtitle_stream;
3124 old_index = is->subtitle_stream;
3126 stream_index = start_index;
3128 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3129 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3131 nb_streams = p->nb_stream_indexes;
3132 for (start_index = 0; start_index < nb_streams; start_index++)
3133 if (p->stream_index[start_index] == stream_index)
3135 if (start_index == nb_streams)
3137 stream_index = start_index;
3142 if (++stream_index >= nb_streams)
3144 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3147 is->last_subtitle_stream = -1;
3150 if (start_index == -1)
3154 if (stream_index == start_index)
3156 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3157 if (st->codecpar->codec_type == codec_type) {
3158 /* check that parameters are OK */
3159 switch (codec_type) {
3160 case AVMEDIA_TYPE_AUDIO:
3161 if (st->codecpar->sample_rate != 0 &&
3162 st->codecpar->channels != 0)
3165 case AVMEDIA_TYPE_VIDEO:
3166 case AVMEDIA_TYPE_SUBTITLE:
3174 if (p && stream_index != -1)
3175 stream_index = p->stream_index[stream_index];
3176 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3177 av_get_media_type_string(codec_type),
3181 stream_component_close(is, old_index);
3182 stream_component_open(is, stream_index);
3186 static void toggle_full_screen(VideoState *is)
3188 is_full_screen = !is_full_screen;
3189 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3192 static void toggle_audio_display(VideoState *is)
3194 int next = is->show_mode;
3196 next = (next + 1) % SHOW_MODE_NB;
3197 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3198 if (is->show_mode != next) {
3199 is->force_refresh = 1;
3200 is->show_mode = next;
3204 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3205 double remaining_time = 0.0;
3207 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3208 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3212 if (remaining_time > 0.0)
3213 av_usleep((int64_t)(remaining_time * 1000000.0));
3214 remaining_time = REFRESH_RATE;
3215 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3216 video_refresh(is, &remaining_time);
3221 static void seek_chapter(VideoState *is, int incr)
3223 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3226 if (!is->ic->nb_chapters)
3229 /* find the current chapter */
3230 for (i = 0; i < is->ic->nb_chapters; i++) {
3231 AVChapter *ch = is->ic->chapters[i];
3232 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3240 if (i >= is->ic->nb_chapters)
3243 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3244 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3245 AV_TIME_BASE_Q), 0, 0);
3248 /* handle an event sent by the GUI */
3249 static void event_loop(VideoState *cur_stream)
3252 double incr, pos, frac;
3256 refresh_loop_wait_event(cur_stream, &event);
3257 switch (event.type) {
3259 if (exit_on_keydown) {
3260 do_exit(cur_stream);
3263 switch (event.key.keysym.sym) {
3266 do_exit(cur_stream);
3269 toggle_full_screen(cur_stream);
3270 cur_stream->force_refresh = 1;
3274 toggle_pause(cur_stream);
3277 toggle_mute(cur_stream);
3279 case SDLK_KP_MULTIPLY:
3281 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3283 case SDLK_KP_DIVIDE:
3285 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3287 case SDLK_s: // S: Step to next frame
3288 step_to_next_frame(cur_stream);
3291 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3294 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3297 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3298 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3299 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3302 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3306 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3307 if (++cur_stream->vfilter_idx >= nb_vfilters)
3308 cur_stream->vfilter_idx = 0;
3310 cur_stream->vfilter_idx = 0;
3311 toggle_audio_display(cur_stream);
3314 toggle_audio_display(cur_stream);
3318 if (cur_stream->ic->nb_chapters <= 1) {
3322 seek_chapter(cur_stream, 1);
3325 if (cur_stream->ic->nb_chapters <= 1) {
3329 seek_chapter(cur_stream, -1);
3343 if (seek_by_bytes) {
3345 if (pos < 0 && cur_stream->video_stream >= 0)
3346 pos = frame_queue_last_pos(&cur_stream->pictq);
3347 if (pos < 0 && cur_stream->audio_stream >= 0)
3348 pos = frame_queue_last_pos(&cur_stream->sampq);
3350 pos = avio_tell(cur_stream->ic->pb);
3351 if (cur_stream->ic->bit_rate)
3352 incr *= cur_stream->ic->bit_rate / 8.0;
3356 stream_seek(cur_stream, pos, incr, 1);
3358 pos = get_master_clock(cur_stream);
3360 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3362 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3363 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3364 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3371 case SDL_MOUSEBUTTONDOWN:
3372 if (exit_on_mousedown) {
3373 do_exit(cur_stream);
3376 if (event.button.button == SDL_BUTTON_LEFT) {
3377 static int64_t last_mouse_left_click = 0;
3378 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3379 toggle_full_screen(cur_stream);
3380 cur_stream->force_refresh = 1;
3381 last_mouse_left_click = 0;
3383 last_mouse_left_click = av_gettime_relative();
3386 case SDL_MOUSEMOTION:
3387 if (cursor_hidden) {
3391 cursor_last_shown = av_gettime_relative();
3392 if (event.type == SDL_MOUSEBUTTONDOWN) {
3393 if (event.button.button != SDL_BUTTON_RIGHT)
3397 if (!(event.motion.state & SDL_BUTTON_RMASK))
3401 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3402 uint64_t size = avio_size(cur_stream->ic->pb);
3403 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3407 int tns, thh, tmm, tss;
3408 tns = cur_stream->ic->duration / 1000000LL;
3410 tmm = (tns % 3600) / 60;
3412 frac = x / cur_stream->width;
3415 mm = (ns % 3600) / 60;
3417 av_log(NULL, AV_LOG_INFO,
3418 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3419 hh, mm, ss, thh, tmm, tss);
3420 ts = frac * cur_stream->ic->duration;
3421 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3422 ts += cur_stream->ic->start_time;
3423 stream_seek(cur_stream, ts, 0, 0);
3426 case SDL_WINDOWEVENT:
3427 switch (event.window.event) {
3428 case SDL_WINDOWEVENT_RESIZED:
3429 screen_width = cur_stream->width = event.window.data1;
3430 screen_height = cur_stream->height = event.window.data2;
3431 if (cur_stream->vis_texture) {
3432 SDL_DestroyTexture(cur_stream->vis_texture);
3433 cur_stream->vis_texture = NULL;
3435 case SDL_WINDOWEVENT_EXPOSED:
3436 cur_stream->force_refresh = 1;
3441 do_exit(cur_stream);
3443 case FF_ALLOC_EVENT:
3444 alloc_picture(event.user.data1);
3452 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3454 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3455 return opt_default(NULL, "video_size", arg);
3458 static int opt_width(void *optctx, const char *opt, const char *arg)
3460 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3464 static int opt_height(void *optctx, const char *opt, const char *arg)
3466 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3470 static int opt_format(void *optctx, const char *opt, const char *arg)
3472 file_iformat = av_find_input_format(arg);
3473 if (!file_iformat) {
3474 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3475 return AVERROR(EINVAL);
3480 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3482 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3483 return opt_default(NULL, "pixel_format", arg);
3486 static int opt_sync(void *optctx, const char *opt, const char *arg)
3488 if (!strcmp(arg, "audio"))
3489 av_sync_type = AV_SYNC_AUDIO_MASTER;
3490 else if (!strcmp(arg, "video"))
3491 av_sync_type = AV_SYNC_VIDEO_MASTER;
3492 else if (!strcmp(arg, "ext"))
3493 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3495 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3501 static int opt_seek(void *optctx, const char *opt, const char *arg)
3503 start_time = parse_time_or_die(opt, arg, 1);
3507 static int opt_duration(void *optctx, const char *opt, const char *arg)
3509 duration = parse_time_or_die(opt, arg, 1);
3513 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3515 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3516 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3517 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3518 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3522 static void opt_input_file(void *optctx, const char *filename)
3524 if (input_filename) {
3525 av_log(NULL, AV_LOG_FATAL,
3526 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3527 filename, input_filename);
3530 if (!strcmp(filename, "-"))
3532 input_filename = filename;
3535 static int opt_codec(void *optctx, const char *opt, const char *arg)
3537 const char *spec = strchr(opt, ':');
3539 av_log(NULL, AV_LOG_ERROR,
3540 "No media specifier was specified in '%s' in option '%s'\n",
3542 return AVERROR(EINVAL);
3546 case 'a' : audio_codec_name = arg; break;
3547 case 's' : subtitle_codec_name = arg; break;
3548 case 'v' : video_codec_name = arg; break;
3550 av_log(NULL, AV_LOG_ERROR,
3551 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3552 return AVERROR(EINVAL);
3559 static const OptionDef options[] = {
3560 #include "cmdutils_common_opts.h"
3561 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3562 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3563 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3564 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3565 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3566 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3567 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3568 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3569 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3570 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3571 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3572 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3573 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3574 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3575 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3576 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3577 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3578 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3579 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3580 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3581 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3582 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3583 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3584 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3585 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3586 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3587 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3588 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3589 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3591 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3592 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3594 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3595 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3596 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3597 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3598 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3599 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3600 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3601 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3602 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3606 static void show_usage(void)
3608 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3609 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3610 av_log(NULL, AV_LOG_INFO, "\n");
3613 void show_help_default(const char *opt, const char *arg)
3615 av_log_set_callback(log_callback_help);
3617 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3618 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3620 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3621 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3622 #if !CONFIG_AVFILTER
3623 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3625 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3627 printf("\nWhile playing:\n"
3629 "f toggle full screen\n"
3632 "9, 0 decrease and increase volume respectively\n"
3633 "/, * decrease and increase volume respectively\n"
3634 "a cycle audio channel in the current program\n"
3635 "v cycle video channel\n"
3636 "t cycle subtitle channel in the current program\n"
3638 "w cycle video filters or show modes\n"
3639 "s activate frame-step mode\n"
3640 "left/right seek backward/forward 10 seconds\n"
3641 "down/up seek backward/forward 1 minute\n"
3642 "page down/page up seek backward/forward 10 minutes\n"
3643 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3644 "left double-click toggle full screen\n"
3648 static int lockmgr(void **mtx, enum AVLockOp op)
3651 case AV_LOCK_CREATE:
3652 *mtx = SDL_CreateMutex();
3654 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3658 case AV_LOCK_OBTAIN:
3659 return !!SDL_LockMutex(*mtx);
3660 case AV_LOCK_RELEASE:
3661 return !!SDL_UnlockMutex(*mtx);
3662 case AV_LOCK_DESTROY:
3663 SDL_DestroyMutex(*mtx);
3669 /* Called from the main */
3670 int main(int argc, char **argv)
3677 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3678 parse_loglevel(argc, argv, options);
3680 /* register all codecs, demux and protocols */
3682 avdevice_register_all();
3685 avfilter_register_all();
3688 avformat_network_init();
3692 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3693 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3695 show_banner(argc, argv, options);
3697 parse_options(NULL, argc, argv, options, opt_input_file);
3699 if (!input_filename) {
3701 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3702 av_log(NULL, AV_LOG_FATAL,
3703 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3707 if (display_disable) {
3710 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3712 flags &= ~SDL_INIT_AUDIO;
3714 /* Try to work around an occasional ALSA buffer underflow issue when the
3715 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3716 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3717 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3719 if (display_disable)
3720 flags &= ~SDL_INIT_VIDEO;
3721 if (SDL_Init (flags)) {
3722 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3723 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3727 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3728 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3730 if (av_lockmgr_register(lockmgr)) {
3731 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3735 av_init_packet(&flush_pkt);
3736 flush_pkt.data = (uint8_t *)&flush_pkt;
3738 is = stream_open(input_filename, file_iformat);
3740 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");