2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
110 static unsigned sws_flags = SWS_BICUBIC;
112 typedef struct MyAVPacketList {
114 struct MyAVPacketList *next;
118 typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
134 typedef struct AudioParams {
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
143 typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
148 int serial; /* clock is based on a packet with this serial */
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
169 typedef struct FrameQueue {
170 Frame queue[FRAME_QUEUE_SIZE];
183 AV_SYNC_AUDIO_MASTER, /* default choice */
184 AV_SYNC_VIDEO_MASTER,
185 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
188 typedef struct Decoder {
192 AVCodecContext *avctx;
196 SDL_cond *empty_queue_cond;
198 AVRational start_pts_tb;
200 AVRational next_pts_tb;
201 SDL_Thread *decoder_tid;
204 typedef struct VideoState {
205 SDL_Thread *read_tid;
206 AVInputFormat *iformat;
211 int queue_attachments_req;
216 int read_pause_return;
237 int audio_clock_serial;
238 double audio_diff_cum; /* used for AV difference average computation */
239 double audio_diff_avg_coef;
240 double audio_diff_threshold;
241 int audio_diff_avg_count;
244 int audio_hw_buf_size;
247 unsigned int audio_buf_size; /* in bytes */
248 unsigned int audio_buf1_size;
249 int audio_buf_index; /* in bytes */
250 int audio_write_buf_size;
253 struct AudioParams audio_src;
255 struct AudioParams audio_filter_src;
257 struct AudioParams audio_tgt;
258 struct SwrContext *swr_ctx;
259 int frame_drops_early;
260 int frame_drops_late;
263 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
265 int16_t sample_array[SAMPLE_ARRAY_SIZE];
266 int sample_array_index;
270 FFTSample *rdft_data;
272 double last_vis_time;
273 SDL_Texture *vis_texture;
274 SDL_Texture *sub_texture;
275 SDL_Texture *vid_texture;
278 AVStream *subtitle_st;
279 PacketQueue subtitleq;
282 double frame_last_returned_time;
283 double frame_last_filter_delay;
287 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
288 struct SwsContext *img_convert_ctx;
289 struct SwsContext *sub_convert_ctx;
293 int width, height, xleft, ytop;
298 AVFilterContext *in_video_filter; // the first filter in the video chain
299 AVFilterContext *out_video_filter; // the last filter in the video chain
300 AVFilterContext *in_audio_filter; // the first filter in the audio chain
301 AVFilterContext *out_audio_filter; // the last filter in the audio chain
302 AVFilterGraph *agraph; // audio filter graph
305 int last_video_stream, last_audio_stream, last_subtitle_stream;
307 SDL_cond *continue_read_thread;
310 /* options specified by the user */
311 static AVInputFormat *file_iformat;
312 static const char *input_filename;
313 static const char *window_title;
314 static int default_width = 640;
315 static int default_height = 480;
316 static int screen_width = 0;
317 static int screen_height = 0;
318 static int audio_disable;
319 static int video_disable;
320 static int subtitle_disable;
321 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
322 static int seek_by_bytes = -1;
323 static int display_disable;
324 static int startup_volume = 100;
325 static int show_status = 1;
326 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
327 static int64_t start_time = AV_NOPTS_VALUE;
328 static int64_t duration = AV_NOPTS_VALUE;
330 static int genpts = 0;
331 static int lowres = 0;
332 static int decoder_reorder_pts = -1;
334 static int exit_on_keydown;
335 static int exit_on_mousedown;
337 static int framedrop = -1;
338 static int infinite_buffer = -1;
339 static enum ShowMode show_mode = SHOW_MODE_NONE;
340 static const char *audio_codec_name;
341 static const char *subtitle_codec_name;
342 static const char *video_codec_name;
343 double rdftspeed = 0.02;
344 static int64_t cursor_last_shown;
345 static int cursor_hidden = 0;
347 static const char **vfilters_list = NULL;
348 static int nb_vfilters = 0;
349 static char *afilters = NULL;
351 static int autorotate = 1;
353 /* current context */
354 static int is_full_screen;
355 static int64_t audio_callback_time;
357 static AVPacket flush_pkt;
359 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
361 static SDL_Window *window;
362 static SDL_Renderer *renderer;
365 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
367 GROW_ARRAY(vfilters_list, nb_vfilters);
368 vfilters_list[nb_vfilters - 1] = arg;
374 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
375 enum AVSampleFormat fmt2, int64_t channel_count2)
377 /* If channel count == 1, planar and non-planar formats are the same */
378 if (channel_count1 == 1 && channel_count2 == 1)
379 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
381 return channel_count1 != channel_count2 || fmt1 != fmt2;
385 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
387 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
388 return channel_layout;
393 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
395 MyAVPacketList *pkt1;
397 if (q->abort_request)
400 pkt1 = av_malloc(sizeof(MyAVPacketList));
405 if (pkt == &flush_pkt)
407 pkt1->serial = q->serial;
412 q->last_pkt->next = pkt1;
415 q->size += pkt1->pkt.size + sizeof(*pkt1);
416 q->duration += pkt1->pkt.duration;
417 /* XXX: should duplicate packet data in DV case */
418 SDL_CondSignal(q->cond);
422 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
426 SDL_LockMutex(q->mutex);
427 ret = packet_queue_put_private(q, pkt);
428 SDL_UnlockMutex(q->mutex);
430 if (pkt != &flush_pkt && ret < 0)
431 av_packet_unref(pkt);
436 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
438 AVPacket pkt1, *pkt = &pkt1;
442 pkt->stream_index = stream_index;
443 return packet_queue_put(q, pkt);
446 /* packet queue handling */
447 static int packet_queue_init(PacketQueue *q)
449 memset(q, 0, sizeof(PacketQueue));
450 q->mutex = SDL_CreateMutex();
452 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
453 return AVERROR(ENOMEM);
455 q->cond = SDL_CreateCond();
457 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
458 return AVERROR(ENOMEM);
460 q->abort_request = 1;
464 static void packet_queue_flush(PacketQueue *q)
466 MyAVPacketList *pkt, *pkt1;
468 SDL_LockMutex(q->mutex);
469 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
471 av_packet_unref(&pkt->pkt);
479 SDL_UnlockMutex(q->mutex);
482 static void packet_queue_destroy(PacketQueue *q)
484 packet_queue_flush(q);
485 SDL_DestroyMutex(q->mutex);
486 SDL_DestroyCond(q->cond);
489 static void packet_queue_abort(PacketQueue *q)
491 SDL_LockMutex(q->mutex);
493 q->abort_request = 1;
495 SDL_CondSignal(q->cond);
497 SDL_UnlockMutex(q->mutex);
500 static void packet_queue_start(PacketQueue *q)
502 SDL_LockMutex(q->mutex);
503 q->abort_request = 0;
504 packet_queue_put_private(q, &flush_pkt);
505 SDL_UnlockMutex(q->mutex);
508 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
509 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
511 MyAVPacketList *pkt1;
514 SDL_LockMutex(q->mutex);
517 if (q->abort_request) {
524 q->first_pkt = pkt1->next;
528 q->size -= pkt1->pkt.size + sizeof(*pkt1);
529 q->duration -= pkt1->pkt.duration;
532 *serial = pkt1->serial;
540 SDL_CondWait(q->cond, q->mutex);
543 SDL_UnlockMutex(q->mutex);
547 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
548 memset(d, 0, sizeof(Decoder));
551 d->empty_queue_cond = empty_queue_cond;
552 d->start_pts = AV_NOPTS_VALUE;
555 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
561 if (d->queue->abort_request)
564 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
567 if (d->queue->nb_packets == 0)
568 SDL_CondSignal(d->empty_queue_cond);
569 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
571 if (pkt.data == flush_pkt.data) {
572 avcodec_flush_buffers(d->avctx);
574 d->next_pts = d->start_pts;
575 d->next_pts_tb = d->start_pts_tb;
577 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
578 av_packet_unref(&d->pkt);
579 d->pkt_temp = d->pkt = pkt;
580 d->packet_pending = 1;
583 switch (d->avctx->codec_type) {
584 case AVMEDIA_TYPE_VIDEO:
585 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
587 if (decoder_reorder_pts == -1) {
588 frame->pts = av_frame_get_best_effort_timestamp(frame);
589 } else if (!decoder_reorder_pts) {
590 frame->pts = frame->pkt_dts;
594 case AVMEDIA_TYPE_AUDIO:
595 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
597 AVRational tb = (AVRational){1, frame->sample_rate};
598 if (frame->pts != AV_NOPTS_VALUE)
599 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
600 else if (d->next_pts != AV_NOPTS_VALUE)
601 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
602 if (frame->pts != AV_NOPTS_VALUE) {
603 d->next_pts = frame->pts + frame->nb_samples;
608 case AVMEDIA_TYPE_SUBTITLE:
609 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
614 d->packet_pending = 0;
617 d->pkt_temp.pts = AV_NOPTS_VALUE;
618 if (d->pkt_temp.data) {
619 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
620 ret = d->pkt_temp.size;
621 d->pkt_temp.data += ret;
622 d->pkt_temp.size -= ret;
623 if (d->pkt_temp.size <= 0)
624 d->packet_pending = 0;
627 d->packet_pending = 0;
628 d->finished = d->pkt_serial;
632 } while (!got_frame && !d->finished);
637 static void decoder_destroy(Decoder *d) {
638 av_packet_unref(&d->pkt);
639 avcodec_free_context(&d->avctx);
642 static void frame_queue_unref_item(Frame *vp)
644 av_frame_unref(vp->frame);
645 avsubtitle_free(&vp->sub);
648 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
651 memset(f, 0, sizeof(FrameQueue));
652 if (!(f->mutex = SDL_CreateMutex())) {
653 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
654 return AVERROR(ENOMEM);
656 if (!(f->cond = SDL_CreateCond())) {
657 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
658 return AVERROR(ENOMEM);
661 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
662 f->keep_last = !!keep_last;
663 for (i = 0; i < f->max_size; i++)
664 if (!(f->queue[i].frame = av_frame_alloc()))
665 return AVERROR(ENOMEM);
669 static void frame_queue_destory(FrameQueue *f)
672 for (i = 0; i < f->max_size; i++) {
673 Frame *vp = &f->queue[i];
674 frame_queue_unref_item(vp);
675 av_frame_free(&vp->frame);
677 SDL_DestroyMutex(f->mutex);
678 SDL_DestroyCond(f->cond);
681 static void frame_queue_signal(FrameQueue *f)
683 SDL_LockMutex(f->mutex);
684 SDL_CondSignal(f->cond);
685 SDL_UnlockMutex(f->mutex);
688 static Frame *frame_queue_peek(FrameQueue *f)
690 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
693 static Frame *frame_queue_peek_next(FrameQueue *f)
695 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
698 static Frame *frame_queue_peek_last(FrameQueue *f)
700 return &f->queue[f->rindex];
703 static Frame *frame_queue_peek_writable(FrameQueue *f)
705 /* wait until we have space to put a new frame */
706 SDL_LockMutex(f->mutex);
707 while (f->size >= f->max_size &&
708 !f->pktq->abort_request) {
709 SDL_CondWait(f->cond, f->mutex);
711 SDL_UnlockMutex(f->mutex);
713 if (f->pktq->abort_request)
716 return &f->queue[f->windex];
719 static Frame *frame_queue_peek_readable(FrameQueue *f)
721 /* wait until we have a readable a new frame */
722 SDL_LockMutex(f->mutex);
723 while (f->size - f->rindex_shown <= 0 &&
724 !f->pktq->abort_request) {
725 SDL_CondWait(f->cond, f->mutex);
727 SDL_UnlockMutex(f->mutex);
729 if (f->pktq->abort_request)
732 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
735 static void frame_queue_push(FrameQueue *f)
737 if (++f->windex == f->max_size)
739 SDL_LockMutex(f->mutex);
741 SDL_CondSignal(f->cond);
742 SDL_UnlockMutex(f->mutex);
745 static void frame_queue_next(FrameQueue *f)
747 if (f->keep_last && !f->rindex_shown) {
751 frame_queue_unref_item(&f->queue[f->rindex]);
752 if (++f->rindex == f->max_size)
754 SDL_LockMutex(f->mutex);
756 SDL_CondSignal(f->cond);
757 SDL_UnlockMutex(f->mutex);
760 /* return the number of undisplayed frames in the queue */
761 static int frame_queue_nb_remaining(FrameQueue *f)
763 return f->size - f->rindex_shown;
766 /* return last shown position */
767 static int64_t frame_queue_last_pos(FrameQueue *f)
769 Frame *fp = &f->queue[f->rindex];
770 if (f->rindex_shown && fp->serial == f->pktq->serial)
776 static void decoder_abort(Decoder *d, FrameQueue *fq)
778 packet_queue_abort(d->queue);
779 frame_queue_signal(fq);
780 SDL_WaitThread(d->decoder_tid, NULL);
781 d->decoder_tid = NULL;
782 packet_queue_flush(d->queue);
785 static inline void fill_rectangle(int x, int y, int w, int h)
793 SDL_RenderFillRect(renderer, &rect);
796 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
800 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
803 SDL_DestroyTexture(*texture);
804 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
806 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
809 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
811 memset(pixels, 0, pitch * new_height);
812 SDL_UnlockTexture(*texture);
818 static void calculate_display_rect(SDL_Rect *rect,
819 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
820 int pic_width, int pic_height, AVRational pic_sar)
823 int width, height, x, y;
825 if (pic_sar.num == 0)
828 aspect_ratio = av_q2d(pic_sar);
830 if (aspect_ratio <= 0.0)
832 aspect_ratio *= (float)pic_width / (float)pic_height;
834 /* XXX: we suppose the screen has a 1.0 pixel ratio */
836 width = lrint(height * aspect_ratio) & ~1;
837 if (width > scr_width) {
839 height = lrint(width / aspect_ratio) & ~1;
841 x = (scr_width - width) / 2;
842 y = (scr_height - height) / 2;
843 rect->x = scr_xleft + x;
844 rect->y = scr_ytop + y;
845 rect->w = FFMAX(width, 1);
846 rect->h = FFMAX(height, 1);
849 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
851 switch (frame->format) {
852 case AV_PIX_FMT_YUV420P:
853 if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
854 av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
857 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
858 frame->data[1], frame->linesize[1],
859 frame->data[2], frame->linesize[2]);
861 case AV_PIX_FMT_BGRA:
862 if (frame->linesize[0] < 0) {
863 ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
865 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
869 /* This should only happen if we are not using avfilter... */
870 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
871 frame->width, frame->height, frame->format, frame->width, frame->height,
872 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
873 if (*img_convert_ctx != NULL) {
876 if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) {
877 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
878 0, frame->height, pixels, pitch);
879 SDL_UnlockTexture(tex);
882 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
890 static void video_image_display(VideoState *is)
896 vp = frame_queue_peek_last(&is->pictq);
897 if (is->subtitle_st) {
898 if (frame_queue_nb_remaining(&is->subpq) > 0) {
899 sp = frame_queue_peek(&is->subpq);
901 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
906 if (!sp->width || !sp->height) {
907 sp->width = vp->width;
908 sp->height = vp->height;
910 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
913 for (i = 0; i < sp->sub.num_rects; i++) {
914 AVSubtitleRect *sub_rect = sp->sub.rects[i];
916 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
917 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
918 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
919 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
921 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
922 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
923 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
924 0, NULL, NULL, NULL);
925 if (!is->sub_convert_ctx) {
926 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
929 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
930 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
931 0, sub_rect->h, pixels, pitch);
932 SDL_UnlockTexture(is->sub_texture);
942 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
945 int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888;
946 if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0)
948 if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
951 vp->flip_v = vp->frame->linesize[0] < 0;
954 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
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);
974 static inline int compute_mod(int a, int b)
976 return a < 0 ? a%b + b : a%b;
979 static void video_audio_display(VideoState *s)
981 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
982 int ch, channels, h, h2;
984 int rdft_bits, nb_freq;
986 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
988 nb_freq = 1 << (rdft_bits - 1);
990 /* compute display index : center on currently output samples */
991 channels = s->audio_tgt.channels;
992 nb_display_channels = channels;
994 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
996 delay = s->audio_write_buf_size;
999 /* to be more precise, we take into account the time spent since
1000 the last buffer computation */
1001 if (audio_callback_time) {
1002 time_diff = av_gettime_relative() - audio_callback_time;
1003 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1006 delay += 2 * data_used;
1007 if (delay < data_used)
1010 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1011 if (s->show_mode == SHOW_MODE_WAVES) {
1013 for (i = 0; i < 1000; i += channels) {
1014 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1015 int a = s->sample_array[idx];
1016 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1017 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1018 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1020 if (h < score && (b ^ c) < 0) {
1027 s->last_i_start = i_start;
1029 i_start = s->last_i_start;
1032 if (s->show_mode == SHOW_MODE_WAVES) {
1033 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1035 /* total height for one channel */
1036 h = s->height / nb_display_channels;
1037 /* graph height / 2 */
1039 for (ch = 0; ch < nb_display_channels; ch++) {
1041 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1042 for (x = 0; x < s->width; x++) {
1043 y = (s->sample_array[i] * h2) >> 15;
1050 fill_rectangle(s->xleft + x, ys, 1, y);
1052 if (i >= SAMPLE_ARRAY_SIZE)
1053 i -= SAMPLE_ARRAY_SIZE;
1057 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1059 for (ch = 1; ch < nb_display_channels; ch++) {
1060 y = s->ytop + ch * h;
1061 fill_rectangle(s->xleft, y, s->width, 1);
1064 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1067 nb_display_channels= FFMIN(nb_display_channels, 2);
1068 if (rdft_bits != s->rdft_bits) {
1069 av_rdft_end(s->rdft);
1070 av_free(s->rdft_data);
1071 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1072 s->rdft_bits = rdft_bits;
1073 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1075 if (!s->rdft || !s->rdft_data){
1076 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1077 s->show_mode = SHOW_MODE_WAVES;
1080 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1083 for (ch = 0; ch < nb_display_channels; ch++) {
1084 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1086 for (x = 0; x < 2 * nb_freq; x++) {
1087 double w = (x-nb_freq) * (1.0 / nb_freq);
1088 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1090 if (i >= SAMPLE_ARRAY_SIZE)
1091 i -= SAMPLE_ARRAY_SIZE;
1093 av_rdft_calc(s->rdft, data[ch]);
1095 /* Least efficient way to do this, we should of course
1096 * directly access it but it is more than fast enough. */
1097 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1099 pixels += pitch * s->height;
1100 for (y = 0; y < s->height; y++) {
1101 double w = 1 / sqrt(nb_freq);
1102 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]));
1103 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1108 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1110 SDL_UnlockTexture(s->vis_texture);
1112 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1116 if (s->xpos >= s->width)
1121 static void stream_component_close(VideoState *is, int stream_index)
1123 AVFormatContext *ic = is->ic;
1124 AVCodecParameters *codecpar;
1126 if (stream_index < 0 || stream_index >= ic->nb_streams)
1128 codecpar = ic->streams[stream_index]->codecpar;
1130 switch (codecpar->codec_type) {
1131 case AVMEDIA_TYPE_AUDIO:
1132 decoder_abort(&is->auddec, &is->sampq);
1134 decoder_destroy(&is->auddec);
1135 swr_free(&is->swr_ctx);
1136 av_freep(&is->audio_buf1);
1137 is->audio_buf1_size = 0;
1138 is->audio_buf = NULL;
1141 av_rdft_end(is->rdft);
1142 av_freep(&is->rdft_data);
1147 case AVMEDIA_TYPE_VIDEO:
1148 decoder_abort(&is->viddec, &is->pictq);
1149 decoder_destroy(&is->viddec);
1151 case AVMEDIA_TYPE_SUBTITLE:
1152 decoder_abort(&is->subdec, &is->subpq);
1153 decoder_destroy(&is->subdec);
1159 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1160 switch (codecpar->codec_type) {
1161 case AVMEDIA_TYPE_AUDIO:
1162 is->audio_st = NULL;
1163 is->audio_stream = -1;
1165 case AVMEDIA_TYPE_VIDEO:
1166 is->video_st = NULL;
1167 is->video_stream = -1;
1169 case AVMEDIA_TYPE_SUBTITLE:
1170 is->subtitle_st = NULL;
1171 is->subtitle_stream = -1;
1178 static void stream_close(VideoState *is)
1180 /* XXX: use a special url_shutdown call to abort parse cleanly */
1181 is->abort_request = 1;
1182 SDL_WaitThread(is->read_tid, NULL);
1184 /* close each stream */
1185 if (is->audio_stream >= 0)
1186 stream_component_close(is, is->audio_stream);
1187 if (is->video_stream >= 0)
1188 stream_component_close(is, is->video_stream);
1189 if (is->subtitle_stream >= 0)
1190 stream_component_close(is, is->subtitle_stream);
1192 avformat_close_input(&is->ic);
1194 packet_queue_destroy(&is->videoq);
1195 packet_queue_destroy(&is->audioq);
1196 packet_queue_destroy(&is->subtitleq);
1198 /* free all pictures */
1199 frame_queue_destory(&is->pictq);
1200 frame_queue_destory(&is->sampq);
1201 frame_queue_destory(&is->subpq);
1202 SDL_DestroyCond(is->continue_read_thread);
1203 sws_freeContext(is->img_convert_ctx);
1204 sws_freeContext(is->sub_convert_ctx);
1205 av_free(is->filename);
1206 if (is->vis_texture)
1207 SDL_DestroyTexture(is->vis_texture);
1208 if (is->vid_texture)
1209 SDL_DestroyTexture(is->vid_texture);
1210 if (is->sub_texture)
1211 SDL_DestroyTexture(is->sub_texture);
1215 static void do_exit(VideoState *is)
1221 SDL_DestroyRenderer(renderer);
1223 SDL_DestroyWindow(window);
1224 av_lockmgr_register(NULL);
1227 av_freep(&vfilters_list);
1229 avformat_network_deinit();
1233 av_log(NULL, AV_LOG_QUIET, "%s", "");
1237 static void sigterm_handler(int sig)
1242 static void set_default_window_size(int width, int height, AVRational sar)
1245 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1246 default_width = rect.w;
1247 default_height = rect.h;
1250 static int video_open(VideoState *is)
1263 int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
1265 window_title = input_filename;
1267 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1268 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1269 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1271 SDL_RendererInfo info;
1272 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1274 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1275 renderer = SDL_CreateRenderer(window, -1, 0);
1278 if (!SDL_GetRendererInfo(renderer, &info))
1279 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1283 SDL_SetWindowSize(window, w, h);
1286 if (!window || !renderer) {
1287 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1297 /* display the current picture, if any */
1298 static void video_display(VideoState *is)
1303 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1304 SDL_RenderClear(renderer);
1305 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1306 video_audio_display(is);
1307 else if (is->video_st)
1308 video_image_display(is);
1309 SDL_RenderPresent(renderer);
1312 static double get_clock(Clock *c)
1314 if (*c->queue_serial != c->serial)
1319 double time = av_gettime_relative() / 1000000.0;
1320 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1324 static void set_clock_at(Clock *c, double pts, int serial, double time)
1327 c->last_updated = time;
1328 c->pts_drift = c->pts - time;
1332 static void set_clock(Clock *c, double pts, int serial)
1334 double time = av_gettime_relative() / 1000000.0;
1335 set_clock_at(c, pts, serial, time);
1338 static void set_clock_speed(Clock *c, double speed)
1340 set_clock(c, get_clock(c), c->serial);
1344 static void init_clock(Clock *c, int *queue_serial)
1348 c->queue_serial = queue_serial;
1349 set_clock(c, NAN, -1);
1352 static void sync_clock_to_slave(Clock *c, Clock *slave)
1354 double clock = get_clock(c);
1355 double slave_clock = get_clock(slave);
1356 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1357 set_clock(c, slave_clock, slave->serial);
1360 static int get_master_sync_type(VideoState *is) {
1361 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1363 return AV_SYNC_VIDEO_MASTER;
1365 return AV_SYNC_AUDIO_MASTER;
1366 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1368 return AV_SYNC_AUDIO_MASTER;
1370 return AV_SYNC_EXTERNAL_CLOCK;
1372 return AV_SYNC_EXTERNAL_CLOCK;
1376 /* get the current master clock value */
1377 static double get_master_clock(VideoState *is)
1381 switch (get_master_sync_type(is)) {
1382 case AV_SYNC_VIDEO_MASTER:
1383 val = get_clock(&is->vidclk);
1385 case AV_SYNC_AUDIO_MASTER:
1386 val = get_clock(&is->audclk);
1389 val = get_clock(&is->extclk);
1395 static void check_external_clock_speed(VideoState *is) {
1396 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1397 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1398 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1399 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1400 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1401 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1403 double speed = is->extclk.speed;
1405 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1409 /* seek in the stream */
1410 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1412 if (!is->seek_req) {
1415 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1417 is->seek_flags |= AVSEEK_FLAG_BYTE;
1419 SDL_CondSignal(is->continue_read_thread);
1423 /* pause or resume the video */
1424 static void stream_toggle_pause(VideoState *is)
1427 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1428 if (is->read_pause_return != AVERROR(ENOSYS)) {
1429 is->vidclk.paused = 0;
1431 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1433 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1434 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1437 static void toggle_pause(VideoState *is)
1439 stream_toggle_pause(is);
1443 static void toggle_mute(VideoState *is)
1445 is->muted = !is->muted;
1448 static void update_volume(VideoState *is, int sign, int step)
1450 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1453 static void step_to_next_frame(VideoState *is)
1455 /* if the stream is paused unpause it, then step */
1457 stream_toggle_pause(is);
1461 static double compute_target_delay(double delay, VideoState *is)
1463 double sync_threshold, diff = 0;
1465 /* update delay to follow master synchronisation source */
1466 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1467 /* if video is slave, we try to correct big delays by
1468 duplicating or deleting a frame */
1469 diff = get_clock(&is->vidclk) - get_master_clock(is);
1471 /* skip or repeat frame. We take into account the
1472 delay to compute the threshold. I still don't know
1473 if it is the best guess */
1474 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1475 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1476 if (diff <= -sync_threshold)
1477 delay = FFMAX(0, delay + diff);
1478 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1479 delay = delay + diff;
1480 else if (diff >= sync_threshold)
1485 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1491 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1492 if (vp->serial == nextvp->serial) {
1493 double duration = nextvp->pts - vp->pts;
1494 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1495 return vp->duration;
1503 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1504 /* update current video pts */
1505 set_clock(&is->vidclk, pts, serial);
1506 sync_clock_to_slave(&is->extclk, &is->vidclk);
1509 /* called to display each frame */
1510 static void video_refresh(void *opaque, double *remaining_time)
1512 VideoState *is = opaque;
1517 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1518 check_external_clock_speed(is);
1520 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1521 time = av_gettime_relative() / 1000000.0;
1522 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1524 is->last_vis_time = time;
1526 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1531 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1532 // nothing to do, no picture to display in the queue
1534 double last_duration, duration, delay;
1537 /* dequeue the picture */
1538 lastvp = frame_queue_peek_last(&is->pictq);
1539 vp = frame_queue_peek(&is->pictq);
1541 if (vp->serial != is->videoq.serial) {
1542 frame_queue_next(&is->pictq);
1546 if (lastvp->serial != vp->serial)
1547 is->frame_timer = av_gettime_relative() / 1000000.0;
1552 /* compute nominal last_duration */
1553 last_duration = vp_duration(is, lastvp, vp);
1554 delay = compute_target_delay(last_duration, is);
1556 time= av_gettime_relative()/1000000.0;
1557 if (time < is->frame_timer + delay) {
1558 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1562 is->frame_timer += delay;
1563 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1564 is->frame_timer = time;
1566 SDL_LockMutex(is->pictq.mutex);
1567 if (!isnan(vp->pts))
1568 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1569 SDL_UnlockMutex(is->pictq.mutex);
1571 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1572 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1573 duration = vp_duration(is, vp, nextvp);
1574 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1575 is->frame_drops_late++;
1576 frame_queue_next(&is->pictq);
1581 if (is->subtitle_st) {
1582 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1583 sp = frame_queue_peek(&is->subpq);
1585 if (frame_queue_nb_remaining(&is->subpq) > 1)
1586 sp2 = frame_queue_peek_next(&is->subpq);
1590 if (sp->serial != is->subtitleq.serial
1591 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1592 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1596 for (i = 0; i < sp->sub.num_rects; i++) {
1597 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1601 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1602 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1603 memset(pixels, 0, sub_rect->w << 2);
1604 SDL_UnlockTexture(is->sub_texture);
1608 frame_queue_next(&is->subpq);
1615 frame_queue_next(&is->pictq);
1616 is->force_refresh = 1;
1618 if (is->step && !is->paused)
1619 stream_toggle_pause(is);
1622 /* display picture */
1623 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1626 is->force_refresh = 0;
1628 static int64_t last_time;
1630 int aqsize, vqsize, sqsize;
1633 cur_time = av_gettime_relative();
1634 if (!last_time || (cur_time - last_time) >= 30000) {
1639 aqsize = is->audioq.size;
1641 vqsize = is->videoq.size;
1642 if (is->subtitle_st)
1643 sqsize = is->subtitleq.size;
1645 if (is->audio_st && is->video_st)
1646 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1647 else if (is->video_st)
1648 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1649 else if (is->audio_st)
1650 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1651 av_log(NULL, AV_LOG_INFO,
1652 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1653 get_master_clock(is),
1654 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1656 is->frame_drops_early + is->frame_drops_late,
1660 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1661 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1663 last_time = cur_time;
1668 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1672 #if defined(DEBUG_SYNC)
1673 printf("frame_type=%c pts=%0.3f\n",
1674 av_get_picture_type_char(src_frame->pict_type), pts);
1677 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1680 vp->sar = src_frame->sample_aspect_ratio;
1683 vp->width = src_frame->width;
1684 vp->height = src_frame->height;
1685 vp->format = src_frame->format;
1688 vp->duration = duration;
1690 vp->serial = serial;
1692 set_default_window_size(vp->width, vp->height, vp->sar);
1694 av_frame_move_ref(vp->frame, src_frame);
1695 frame_queue_push(&is->pictq);
1699 static int get_video_frame(VideoState *is, AVFrame *frame)
1703 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1709 if (frame->pts != AV_NOPTS_VALUE)
1710 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1712 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1714 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1715 if (frame->pts != AV_NOPTS_VALUE) {
1716 double diff = dpts - get_master_clock(is);
1717 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1718 diff - is->frame_last_filter_delay < 0 &&
1719 is->viddec.pkt_serial == is->vidclk.serial &&
1720 is->videoq.nb_packets) {
1721 is->frame_drops_early++;
1722 av_frame_unref(frame);
1733 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1734 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1737 int nb_filters = graph->nb_filters;
1738 AVFilterInOut *outputs = NULL, *inputs = NULL;
1741 outputs = avfilter_inout_alloc();
1742 inputs = avfilter_inout_alloc();
1743 if (!outputs || !inputs) {
1744 ret = AVERROR(ENOMEM);
1748 outputs->name = av_strdup("in");
1749 outputs->filter_ctx = source_ctx;
1750 outputs->pad_idx = 0;
1751 outputs->next = NULL;
1753 inputs->name = av_strdup("out");
1754 inputs->filter_ctx = sink_ctx;
1755 inputs->pad_idx = 0;
1756 inputs->next = NULL;
1758 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1761 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1765 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1766 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1767 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1769 ret = avfilter_graph_config(graph, NULL);
1771 avfilter_inout_free(&outputs);
1772 avfilter_inout_free(&inputs);
1776 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1778 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1779 char sws_flags_str[512] = "";
1780 char buffersrc_args[256];
1782 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1783 AVCodecParameters *codecpar = is->video_st->codecpar;
1784 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1785 AVDictionaryEntry *e = NULL;
1787 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1788 if (!strcmp(e->key, "sws_flags")) {
1789 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1791 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1793 if (strlen(sws_flags_str))
1794 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1796 graph->scale_sws_opts = av_strdup(sws_flags_str);
1798 snprintf(buffersrc_args, sizeof(buffersrc_args),
1799 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1800 frame->width, frame->height, frame->format,
1801 is->video_st->time_base.num, is->video_st->time_base.den,
1802 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1803 if (fr.num && fr.den)
1804 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1806 if ((ret = avfilter_graph_create_filter(&filt_src,
1807 avfilter_get_by_name("buffer"),
1808 "ffplay_buffer", buffersrc_args, NULL,
1812 ret = avfilter_graph_create_filter(&filt_out,
1813 avfilter_get_by_name("buffersink"),
1814 "ffplay_buffersink", NULL, NULL, graph);
1818 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1821 last_filter = filt_out;
1823 /* Note: this macro adds a filter before the lastly added filter, so the
1824 * processing order of the filters is in reverse */
1825 #define INSERT_FILT(name, arg) do { \
1826 AVFilterContext *filt_ctx; \
1828 ret = avfilter_graph_create_filter(&filt_ctx, \
1829 avfilter_get_by_name(name), \
1830 "ffplay_" name, arg, NULL, graph); \
1834 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1838 last_filter = filt_ctx; \
1842 double theta = get_rotation(is->video_st);
1844 if (fabs(theta - 90) < 1.0) {
1845 INSERT_FILT("transpose", "clock");
1846 } else if (fabs(theta - 180) < 1.0) {
1847 INSERT_FILT("hflip", NULL);
1848 INSERT_FILT("vflip", NULL);
1849 } else if (fabs(theta - 270) < 1.0) {
1850 INSERT_FILT("transpose", "cclock");
1851 } else if (fabs(theta) > 1.0) {
1852 char rotate_buf[64];
1853 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1854 INSERT_FILT("rotate", rotate_buf);
1858 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1861 is->in_video_filter = filt_src;
1862 is->out_video_filter = filt_out;
1868 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1870 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1871 int sample_rates[2] = { 0, -1 };
1872 int64_t channel_layouts[2] = { 0, -1 };
1873 int channels[2] = { 0, -1 };
1874 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1875 char aresample_swr_opts[512] = "";
1876 AVDictionaryEntry *e = NULL;
1877 char asrc_args[256];
1880 avfilter_graph_free(&is->agraph);
1881 if (!(is->agraph = avfilter_graph_alloc()))
1882 return AVERROR(ENOMEM);
1884 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1885 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1886 if (strlen(aresample_swr_opts))
1887 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1888 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1890 ret = snprintf(asrc_args, sizeof(asrc_args),
1891 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1892 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1893 is->audio_filter_src.channels,
1894 1, is->audio_filter_src.freq);
1895 if (is->audio_filter_src.channel_layout)
1896 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1897 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1899 ret = avfilter_graph_create_filter(&filt_asrc,
1900 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1901 asrc_args, NULL, is->agraph);
1906 ret = avfilter_graph_create_filter(&filt_asink,
1907 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1908 NULL, NULL, is->agraph);
1912 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1914 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1917 if (force_output_format) {
1918 channel_layouts[0] = is->audio_tgt.channel_layout;
1919 channels [0] = is->audio_tgt.channels;
1920 sample_rates [0] = is->audio_tgt.freq;
1921 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1923 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1925 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1927 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1932 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1935 is->in_audio_filter = filt_asrc;
1936 is->out_audio_filter = filt_asink;
1940 avfilter_graph_free(&is->agraph);
1943 #endif /* CONFIG_AVFILTER */
1945 static int audio_thread(void *arg)
1947 VideoState *is = arg;
1948 AVFrame *frame = av_frame_alloc();
1951 int last_serial = -1;
1952 int64_t dec_channel_layout;
1960 return AVERROR(ENOMEM);
1963 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1967 tb = (AVRational){1, frame->sample_rate};
1970 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
1973 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
1974 frame->format, av_frame_get_channels(frame)) ||
1975 is->audio_filter_src.channel_layout != dec_channel_layout ||
1976 is->audio_filter_src.freq != frame->sample_rate ||
1977 is->auddec.pkt_serial != last_serial;
1980 char buf1[1024], buf2[1024];
1981 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
1982 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
1983 av_log(NULL, AV_LOG_DEBUG,
1984 "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",
1985 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
1986 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
1988 is->audio_filter_src.fmt = frame->format;
1989 is->audio_filter_src.channels = av_frame_get_channels(frame);
1990 is->audio_filter_src.channel_layout = dec_channel_layout;
1991 is->audio_filter_src.freq = frame->sample_rate;
1992 last_serial = is->auddec.pkt_serial;
1994 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
1998 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2001 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2002 tb = av_buffersink_get_time_base(is->out_audio_filter);
2004 if (!(af = frame_queue_peek_writable(&is->sampq)))
2007 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2008 af->pos = av_frame_get_pkt_pos(frame);
2009 af->serial = is->auddec.pkt_serial;
2010 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2012 av_frame_move_ref(af->frame, frame);
2013 frame_queue_push(&is->sampq);
2016 if (is->audioq.serial != is->auddec.pkt_serial)
2019 if (ret == AVERROR_EOF)
2020 is->auddec.finished = is->auddec.pkt_serial;
2023 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2026 avfilter_graph_free(&is->agraph);
2028 av_frame_free(&frame);
2032 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2034 packet_queue_start(d->queue);
2035 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2036 if (!d->decoder_tid) {
2037 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2038 return AVERROR(ENOMEM);
2043 static int video_thread(void *arg)
2045 VideoState *is = arg;
2046 AVFrame *frame = av_frame_alloc();
2050 AVRational tb = is->video_st->time_base;
2051 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2054 AVFilterGraph *graph = avfilter_graph_alloc();
2055 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2058 enum AVPixelFormat last_format = -2;
2059 int last_serial = -1;
2060 int last_vfilter_idx = 0;
2062 av_frame_free(&frame);
2063 return AVERROR(ENOMEM);
2070 avfilter_graph_free(&graph);
2072 return AVERROR(ENOMEM);
2076 ret = get_video_frame(is, frame);
2083 if ( last_w != frame->width
2084 || last_h != frame->height
2085 || last_format != frame->format
2086 || last_serial != is->viddec.pkt_serial
2087 || last_vfilter_idx != is->vfilter_idx) {
2088 av_log(NULL, AV_LOG_DEBUG,
2089 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2091 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2092 frame->width, frame->height,
2093 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2094 avfilter_graph_free(&graph);
2095 graph = avfilter_graph_alloc();
2096 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2098 event.type = FF_QUIT_EVENT;
2099 event.user.data1 = is;
2100 SDL_PushEvent(&event);
2103 filt_in = is->in_video_filter;
2104 filt_out = is->out_video_filter;
2105 last_w = frame->width;
2106 last_h = frame->height;
2107 last_format = frame->format;
2108 last_serial = is->viddec.pkt_serial;
2109 last_vfilter_idx = is->vfilter_idx;
2110 frame_rate = av_buffersink_get_frame_rate(filt_out);
2113 ret = av_buffersrc_add_frame(filt_in, frame);
2118 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2120 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2122 if (ret == AVERROR_EOF)
2123 is->viddec.finished = is->viddec.pkt_serial;
2128 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2129 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2130 is->frame_last_filter_delay = 0;
2131 tb = av_buffersink_get_time_base(filt_out);
2133 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2134 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2135 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2136 av_frame_unref(frame);
2146 avfilter_graph_free(&graph);
2148 av_frame_free(&frame);
2152 static int subtitle_thread(void *arg)
2154 VideoState *is = arg;
2160 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2163 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2168 if (got_subtitle && sp->sub.format == 0) {
2169 if (sp->sub.pts != AV_NOPTS_VALUE)
2170 pts = sp->sub.pts / (double)AV_TIME_BASE;
2172 sp->serial = is->subdec.pkt_serial;
2173 sp->width = is->subdec.avctx->width;
2174 sp->height = is->subdec.avctx->height;
2177 /* now we can update the picture count */
2178 frame_queue_push(&is->subpq);
2179 } else if (got_subtitle) {
2180 avsubtitle_free(&sp->sub);
2186 /* copy samples for viewing in editor window */
2187 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2191 size = samples_size / sizeof(short);
2193 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2196 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2198 is->sample_array_index += len;
2199 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2200 is->sample_array_index = 0;
2205 /* return the wanted number of samples to get better sync if sync_type is video
2206 * or external master clock */
2207 static int synchronize_audio(VideoState *is, int nb_samples)
2209 int wanted_nb_samples = nb_samples;
2211 /* if not master, then we try to remove or add samples to correct the clock */
2212 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2213 double diff, avg_diff;
2214 int min_nb_samples, max_nb_samples;
2216 diff = get_clock(&is->audclk) - get_master_clock(is);
2218 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2219 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2220 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2221 /* not enough measures to have a correct estimate */
2222 is->audio_diff_avg_count++;
2224 /* estimate the A-V difference */
2225 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2227 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2228 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2229 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2230 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2231 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2233 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2234 diff, avg_diff, wanted_nb_samples - nb_samples,
2235 is->audio_clock, is->audio_diff_threshold);
2238 /* too big difference : may be initial PTS errors, so
2240 is->audio_diff_avg_count = 0;
2241 is->audio_diff_cum = 0;
2245 return wanted_nb_samples;
2249 * Decode one audio frame and return its uncompressed size.
2251 * The processed audio frame is decoded, converted if required, and
2252 * stored in is->audio_buf, with size in bytes given by the return
2255 static int audio_decode_frame(VideoState *is)
2257 int data_size, resampled_data_size;
2258 int64_t dec_channel_layout;
2259 av_unused double audio_clock0;
2260 int wanted_nb_samples;
2268 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2269 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2274 if (!(af = frame_queue_peek_readable(&is->sampq)))
2276 frame_queue_next(&is->sampq);
2277 } while (af->serial != is->audioq.serial);
2279 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2280 af->frame->nb_samples,
2281 af->frame->format, 1);
2283 dec_channel_layout =
2284 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2285 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2286 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2288 if (af->frame->format != is->audio_src.fmt ||
2289 dec_channel_layout != is->audio_src.channel_layout ||
2290 af->frame->sample_rate != is->audio_src.freq ||
2291 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2292 swr_free(&is->swr_ctx);
2293 is->swr_ctx = swr_alloc_set_opts(NULL,
2294 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2295 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2297 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2298 av_log(NULL, AV_LOG_ERROR,
2299 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2300 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2301 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2302 swr_free(&is->swr_ctx);
2305 is->audio_src.channel_layout = dec_channel_layout;
2306 is->audio_src.channels = av_frame_get_channels(af->frame);
2307 is->audio_src.freq = af->frame->sample_rate;
2308 is->audio_src.fmt = af->frame->format;
2312 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2313 uint8_t **out = &is->audio_buf1;
2314 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2315 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2318 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2321 if (wanted_nb_samples != af->frame->nb_samples) {
2322 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2323 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2324 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2328 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2329 if (!is->audio_buf1)
2330 return AVERROR(ENOMEM);
2331 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2333 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2336 if (len2 == out_count) {
2337 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2338 if (swr_init(is->swr_ctx) < 0)
2339 swr_free(&is->swr_ctx);
2341 is->audio_buf = is->audio_buf1;
2342 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2344 is->audio_buf = af->frame->data[0];
2345 resampled_data_size = data_size;
2348 audio_clock0 = is->audio_clock;
2349 /* update the audio clock with the pts */
2350 if (!isnan(af->pts))
2351 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2353 is->audio_clock = NAN;
2354 is->audio_clock_serial = af->serial;
2357 static double last_clock;
2358 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2359 is->audio_clock - last_clock,
2360 is->audio_clock, audio_clock0);
2361 last_clock = is->audio_clock;
2364 return resampled_data_size;
2367 /* prepare a new audio buffer */
2368 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2370 VideoState *is = opaque;
2371 int audio_size, len1;
2373 audio_callback_time = av_gettime_relative();
2376 if (is->audio_buf_index >= is->audio_buf_size) {
2377 audio_size = audio_decode_frame(is);
2378 if (audio_size < 0) {
2379 /* if error, just output silence */
2380 is->audio_buf = NULL;
2381 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2383 if (is->show_mode != SHOW_MODE_VIDEO)
2384 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2385 is->audio_buf_size = audio_size;
2387 is->audio_buf_index = 0;
2389 len1 = is->audio_buf_size - is->audio_buf_index;
2392 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2393 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2395 memset(stream, 0, len1);
2396 if (!is->muted && is->audio_buf)
2397 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2401 is->audio_buf_index += len1;
2403 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2404 /* Let's assume the audio driver that is used by SDL has two periods. */
2405 if (!isnan(is->audio_clock)) {
2406 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);
2407 sync_clock_to_slave(&is->extclk, &is->audclk);
2411 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2413 SDL_AudioSpec wanted_spec, spec;
2415 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2416 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2417 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2419 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2421 wanted_nb_channels = atoi(env);
2422 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2424 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2425 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2426 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2428 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2429 wanted_spec.channels = wanted_nb_channels;
2430 wanted_spec.freq = wanted_sample_rate;
2431 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2432 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2435 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2436 next_sample_rate_idx--;
2437 wanted_spec.format = AUDIO_S16SYS;
2438 wanted_spec.silence = 0;
2439 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2440 wanted_spec.callback = sdl_audio_callback;
2441 wanted_spec.userdata = opaque;
2442 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2443 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2444 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2445 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2446 if (!wanted_spec.channels) {
2447 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2448 wanted_spec.channels = wanted_nb_channels;
2449 if (!wanted_spec.freq) {
2450 av_log(NULL, AV_LOG_ERROR,
2451 "No more combinations to try, audio open failed\n");
2455 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2457 if (spec.format != AUDIO_S16SYS) {
2458 av_log(NULL, AV_LOG_ERROR,
2459 "SDL advised audio format %d is not supported!\n", spec.format);
2462 if (spec.channels != wanted_spec.channels) {
2463 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2464 if (!wanted_channel_layout) {
2465 av_log(NULL, AV_LOG_ERROR,
2466 "SDL advised channel count %d is not supported!\n", spec.channels);
2471 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2472 audio_hw_params->freq = spec.freq;
2473 audio_hw_params->channel_layout = wanted_channel_layout;
2474 audio_hw_params->channels = spec.channels;
2475 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2476 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);
2477 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2478 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2484 /* open a given stream. Return 0 if OK */
2485 static int stream_component_open(VideoState *is, int stream_index)
2487 AVFormatContext *ic = is->ic;
2488 AVCodecContext *avctx;
2490 const char *forced_codec_name = NULL;
2491 AVDictionary *opts = NULL;
2492 AVDictionaryEntry *t = NULL;
2493 int sample_rate, nb_channels;
2494 int64_t channel_layout;
2496 int stream_lowres = lowres;
2498 if (stream_index < 0 || stream_index >= ic->nb_streams)
2501 avctx = avcodec_alloc_context3(NULL);
2503 return AVERROR(ENOMEM);
2505 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2508 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2510 codec = avcodec_find_decoder(avctx->codec_id);
2512 switch(avctx->codec_type){
2513 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2514 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2515 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2517 if (forced_codec_name)
2518 codec = avcodec_find_decoder_by_name(forced_codec_name);
2520 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2521 "No codec could be found with name '%s'\n", forced_codec_name);
2522 else av_log(NULL, AV_LOG_WARNING,
2523 "No codec could be found with id %d\n", avctx->codec_id);
2524 ret = AVERROR(EINVAL);
2528 avctx->codec_id = codec->id;
2529 if(stream_lowres > av_codec_get_max_lowres(codec)){
2530 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2531 av_codec_get_max_lowres(codec));
2532 stream_lowres = av_codec_get_max_lowres(codec);
2534 av_codec_set_lowres(avctx, stream_lowres);
2537 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2540 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2542 if(codec->capabilities & AV_CODEC_CAP_DR1)
2543 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2546 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2547 if (!av_dict_get(opts, "threads", NULL, 0))
2548 av_dict_set(&opts, "threads", "auto", 0);
2550 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2551 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2552 av_dict_set(&opts, "refcounted_frames", "1", 0);
2553 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2556 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2557 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2558 ret = AVERROR_OPTION_NOT_FOUND;
2563 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2564 switch (avctx->codec_type) {
2565 case AVMEDIA_TYPE_AUDIO:
2568 AVFilterContext *sink;
2570 is->audio_filter_src.freq = avctx->sample_rate;
2571 is->audio_filter_src.channels = avctx->channels;
2572 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2573 is->audio_filter_src.fmt = avctx->sample_fmt;
2574 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2576 sink = is->out_audio_filter;
2577 sample_rate = av_buffersink_get_sample_rate(sink);
2578 nb_channels = av_buffersink_get_channels(sink);
2579 channel_layout = av_buffersink_get_channel_layout(sink);
2582 sample_rate = avctx->sample_rate;
2583 nb_channels = avctx->channels;
2584 channel_layout = avctx->channel_layout;
2587 /* prepare audio output */
2588 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2590 is->audio_hw_buf_size = ret;
2591 is->audio_src = is->audio_tgt;
2592 is->audio_buf_size = 0;
2593 is->audio_buf_index = 0;
2595 /* init averaging filter */
2596 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2597 is->audio_diff_avg_count = 0;
2598 /* since we do not have a precise anough audio FIFO fullness,
2599 we correct audio sync only if larger than this threshold */
2600 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2602 is->audio_stream = stream_index;
2603 is->audio_st = ic->streams[stream_index];
2605 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2606 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2607 is->auddec.start_pts = is->audio_st->start_time;
2608 is->auddec.start_pts_tb = is->audio_st->time_base;
2610 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2614 case AVMEDIA_TYPE_VIDEO:
2615 is->video_stream = stream_index;
2616 is->video_st = ic->streams[stream_index];
2618 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2619 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2621 is->queue_attachments_req = 1;
2623 case AVMEDIA_TYPE_SUBTITLE:
2624 is->subtitle_stream = stream_index;
2625 is->subtitle_st = ic->streams[stream_index];
2627 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2628 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2637 avcodec_free_context(&avctx);
2639 av_dict_free(&opts);
2644 static int decode_interrupt_cb(void *ctx)
2646 VideoState *is = ctx;
2647 return is->abort_request;
2650 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2651 return stream_id < 0 ||
2652 queue->abort_request ||
2653 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2654 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2657 static int is_realtime(AVFormatContext *s)
2659 if( !strcmp(s->iformat->name, "rtp")
2660 || !strcmp(s->iformat->name, "rtsp")
2661 || !strcmp(s->iformat->name, "sdp")
2665 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2666 || !strncmp(s->filename, "udp:", 4)
2673 /* this thread gets the stream from the disk or the network */
2674 static int read_thread(void *arg)
2676 VideoState *is = arg;
2677 AVFormatContext *ic = NULL;
2679 int st_index[AVMEDIA_TYPE_NB];
2680 AVPacket pkt1, *pkt = &pkt1;
2681 int64_t stream_start_time;
2682 int pkt_in_play_range = 0;
2683 AVDictionaryEntry *t;
2684 AVDictionary **opts;
2685 int orig_nb_streams;
2686 SDL_mutex *wait_mutex = SDL_CreateMutex();
2687 int scan_all_pmts_set = 0;
2691 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2692 ret = AVERROR(ENOMEM);
2696 memset(st_index, -1, sizeof(st_index));
2697 is->last_video_stream = is->video_stream = -1;
2698 is->last_audio_stream = is->audio_stream = -1;
2699 is->last_subtitle_stream = is->subtitle_stream = -1;
2702 ic = avformat_alloc_context();
2704 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2705 ret = AVERROR(ENOMEM);
2708 ic->interrupt_callback.callback = decode_interrupt_cb;
2709 ic->interrupt_callback.opaque = is;
2710 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2711 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2712 scan_all_pmts_set = 1;
2714 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2716 print_error(is->filename, err);
2720 if (scan_all_pmts_set)
2721 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2723 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2724 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2725 ret = AVERROR_OPTION_NOT_FOUND;
2731 ic->flags |= AVFMT_FLAG_GENPTS;
2733 av_format_inject_global_side_data(ic);
2735 opts = setup_find_stream_info_opts(ic, codec_opts);
2736 orig_nb_streams = ic->nb_streams;
2738 err = avformat_find_stream_info(ic, opts);
2740 for (i = 0; i < orig_nb_streams; i++)
2741 av_dict_free(&opts[i]);
2745 av_log(NULL, AV_LOG_WARNING,
2746 "%s: could not find codec parameters\n", is->filename);
2752 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2754 if (seek_by_bytes < 0)
2755 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2757 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2759 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2760 window_title = av_asprintf("%s - %s", t->value, input_filename);
2762 /* if seeking requested, we execute it */
2763 if (start_time != AV_NOPTS_VALUE) {
2766 timestamp = start_time;
2767 /* add the stream start time */
2768 if (ic->start_time != AV_NOPTS_VALUE)
2769 timestamp += ic->start_time;
2770 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2772 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2773 is->filename, (double)timestamp / AV_TIME_BASE);
2777 is->realtime = is_realtime(ic);
2780 av_dump_format(ic, 0, is->filename, 0);
2782 for (i = 0; i < ic->nb_streams; i++) {
2783 AVStream *st = ic->streams[i];
2784 enum AVMediaType type = st->codecpar->codec_type;
2785 st->discard = AVDISCARD_ALL;
2786 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2787 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2790 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2791 if (wanted_stream_spec[i] && st_index[i] == -1) {
2792 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));
2793 st_index[i] = INT_MAX;
2798 st_index[AVMEDIA_TYPE_VIDEO] =
2799 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2800 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2802 st_index[AVMEDIA_TYPE_AUDIO] =
2803 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2804 st_index[AVMEDIA_TYPE_AUDIO],
2805 st_index[AVMEDIA_TYPE_VIDEO],
2807 if (!video_disable && !subtitle_disable)
2808 st_index[AVMEDIA_TYPE_SUBTITLE] =
2809 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2810 st_index[AVMEDIA_TYPE_SUBTITLE],
2811 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2812 st_index[AVMEDIA_TYPE_AUDIO] :
2813 st_index[AVMEDIA_TYPE_VIDEO]),
2816 is->show_mode = show_mode;
2817 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2818 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2819 AVCodecParameters *codecpar = st->codecpar;
2820 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2821 if (codecpar->width)
2822 set_default_window_size(codecpar->width, codecpar->height, sar);
2825 /* open the streams */
2826 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2827 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2831 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2832 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2834 if (is->show_mode == SHOW_MODE_NONE)
2835 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2837 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2838 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2841 if (is->video_stream < 0 && is->audio_stream < 0) {
2842 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2848 if (infinite_buffer < 0 && is->realtime)
2849 infinite_buffer = 1;
2852 if (is->abort_request)
2854 if (is->paused != is->last_paused) {
2855 is->last_paused = is->paused;
2857 is->read_pause_return = av_read_pause(ic);
2861 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2863 (!strcmp(ic->iformat->name, "rtsp") ||
2864 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2865 /* wait 10 ms to avoid trying to get another packet */
2872 int64_t seek_target = is->seek_pos;
2873 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2874 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2875 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2876 // of the seek_pos/seek_rel variables
2878 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2880 av_log(NULL, AV_LOG_ERROR,
2881 "%s: error while seeking\n", is->ic->filename);
2883 if (is->audio_stream >= 0) {
2884 packet_queue_flush(&is->audioq);
2885 packet_queue_put(&is->audioq, &flush_pkt);
2887 if (is->subtitle_stream >= 0) {
2888 packet_queue_flush(&is->subtitleq);
2889 packet_queue_put(&is->subtitleq, &flush_pkt);
2891 if (is->video_stream >= 0) {
2892 packet_queue_flush(&is->videoq);
2893 packet_queue_put(&is->videoq, &flush_pkt);
2895 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2896 set_clock(&is->extclk, NAN, 0);
2898 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2902 is->queue_attachments_req = 1;
2905 step_to_next_frame(is);
2907 if (is->queue_attachments_req) {
2908 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2910 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2912 packet_queue_put(&is->videoq, ©);
2913 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2915 is->queue_attachments_req = 0;
2918 /* if the queue are full, no need to read more */
2919 if (infinite_buffer<1 &&
2920 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2921 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2922 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2923 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2925 SDL_LockMutex(wait_mutex);
2926 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2927 SDL_UnlockMutex(wait_mutex);
2931 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2932 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2933 if (loop != 1 && (!loop || --loop)) {
2934 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2935 } else if (autoexit) {
2940 ret = av_read_frame(ic, pkt);
2942 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
2943 if (is->video_stream >= 0)
2944 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2945 if (is->audio_stream >= 0)
2946 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2947 if (is->subtitle_stream >= 0)
2948 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
2951 if (ic->pb && ic->pb->error)
2953 SDL_LockMutex(wait_mutex);
2954 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2955 SDL_UnlockMutex(wait_mutex);
2960 /* check if packet is in play range specified by user, then queue, otherwise discard */
2961 stream_start_time = ic->streams[pkt->stream_index]->start_time;
2962 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
2963 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2964 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
2965 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2966 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2967 <= ((double)duration / 1000000);
2968 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2969 packet_queue_put(&is->audioq, pkt);
2970 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2971 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
2972 packet_queue_put(&is->videoq, pkt);
2973 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2974 packet_queue_put(&is->subtitleq, pkt);
2976 av_packet_unref(pkt);
2983 avformat_close_input(&ic);
2988 event.type = FF_QUIT_EVENT;
2989 event.user.data1 = is;
2990 SDL_PushEvent(&event);
2992 SDL_DestroyMutex(wait_mutex);
2996 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3000 is = av_mallocz(sizeof(VideoState));
3003 is->filename = av_strdup(filename);
3006 is->iformat = iformat;
3010 /* start video display */
3011 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3013 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3015 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3018 if (packet_queue_init(&is->videoq) < 0 ||
3019 packet_queue_init(&is->audioq) < 0 ||
3020 packet_queue_init(&is->subtitleq) < 0)
3023 if (!(is->continue_read_thread = SDL_CreateCond())) {
3024 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3028 init_clock(&is->vidclk, &is->videoq.serial);
3029 init_clock(&is->audclk, &is->audioq.serial);
3030 init_clock(&is->extclk, &is->extclk.serial);
3031 is->audio_clock_serial = -1;
3032 if (startup_volume < 0)
3033 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3034 if (startup_volume > 100)
3035 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3036 startup_volume = av_clip(startup_volume, 0, 100);
3037 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3038 is->audio_volume = startup_volume;
3040 is->av_sync_type = av_sync_type;
3041 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3042 if (!is->read_tid) {
3043 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3051 static void stream_cycle_channel(VideoState *is, int codec_type)
3053 AVFormatContext *ic = is->ic;
3054 int start_index, stream_index;
3057 AVProgram *p = NULL;
3058 int nb_streams = is->ic->nb_streams;
3060 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3061 start_index = is->last_video_stream;
3062 old_index = is->video_stream;
3063 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3064 start_index = is->last_audio_stream;
3065 old_index = is->audio_stream;
3067 start_index = is->last_subtitle_stream;
3068 old_index = is->subtitle_stream;
3070 stream_index = start_index;
3072 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3073 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3075 nb_streams = p->nb_stream_indexes;
3076 for (start_index = 0; start_index < nb_streams; start_index++)
3077 if (p->stream_index[start_index] == stream_index)
3079 if (start_index == nb_streams)
3081 stream_index = start_index;
3086 if (++stream_index >= nb_streams)
3088 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3091 is->last_subtitle_stream = -1;
3094 if (start_index == -1)
3098 if (stream_index == start_index)
3100 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3101 if (st->codecpar->codec_type == codec_type) {
3102 /* check that parameters are OK */
3103 switch (codec_type) {
3104 case AVMEDIA_TYPE_AUDIO:
3105 if (st->codecpar->sample_rate != 0 &&
3106 st->codecpar->channels != 0)
3109 case AVMEDIA_TYPE_VIDEO:
3110 case AVMEDIA_TYPE_SUBTITLE:
3118 if (p && stream_index != -1)
3119 stream_index = p->stream_index[stream_index];
3120 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3121 av_get_media_type_string(codec_type),
3125 stream_component_close(is, old_index);
3126 stream_component_open(is, stream_index);
3130 static void toggle_full_screen(VideoState *is)
3132 is_full_screen = !is_full_screen;
3133 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3136 static void toggle_audio_display(VideoState *is)
3138 int next = is->show_mode;
3140 next = (next + 1) % SHOW_MODE_NB;
3141 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3142 if (is->show_mode != next) {
3143 is->force_refresh = 1;
3144 is->show_mode = next;
3148 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3149 double remaining_time = 0.0;
3151 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3152 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3156 if (remaining_time > 0.0)
3157 av_usleep((int64_t)(remaining_time * 1000000.0));
3158 remaining_time = REFRESH_RATE;
3159 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3160 video_refresh(is, &remaining_time);
3165 static void seek_chapter(VideoState *is, int incr)
3167 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3170 if (!is->ic->nb_chapters)
3173 /* find the current chapter */
3174 for (i = 0; i < is->ic->nb_chapters; i++) {
3175 AVChapter *ch = is->ic->chapters[i];
3176 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3184 if (i >= is->ic->nb_chapters)
3187 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3188 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3189 AV_TIME_BASE_Q), 0, 0);
3192 /* handle an event sent by the GUI */
3193 static void event_loop(VideoState *cur_stream)
3196 double incr, pos, frac;
3200 refresh_loop_wait_event(cur_stream, &event);
3201 switch (event.type) {
3203 if (exit_on_keydown) {
3204 do_exit(cur_stream);
3207 switch (event.key.keysym.sym) {
3210 do_exit(cur_stream);
3213 toggle_full_screen(cur_stream);
3214 cur_stream->force_refresh = 1;
3218 toggle_pause(cur_stream);
3221 toggle_mute(cur_stream);
3223 case SDLK_KP_MULTIPLY:
3225 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3227 case SDLK_KP_DIVIDE:
3229 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3231 case SDLK_s: // S: Step to next frame
3232 step_to_next_frame(cur_stream);
3235 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3238 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3241 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3242 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3243 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3246 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3250 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3251 if (++cur_stream->vfilter_idx >= nb_vfilters)
3252 cur_stream->vfilter_idx = 0;
3254 cur_stream->vfilter_idx = 0;
3255 toggle_audio_display(cur_stream);
3258 toggle_audio_display(cur_stream);
3262 if (cur_stream->ic->nb_chapters <= 1) {
3266 seek_chapter(cur_stream, 1);
3269 if (cur_stream->ic->nb_chapters <= 1) {
3273 seek_chapter(cur_stream, -1);
3287 if (seek_by_bytes) {
3289 if (pos < 0 && cur_stream->video_stream >= 0)
3290 pos = frame_queue_last_pos(&cur_stream->pictq);
3291 if (pos < 0 && cur_stream->audio_stream >= 0)
3292 pos = frame_queue_last_pos(&cur_stream->sampq);
3294 pos = avio_tell(cur_stream->ic->pb);
3295 if (cur_stream->ic->bit_rate)
3296 incr *= cur_stream->ic->bit_rate / 8.0;
3300 stream_seek(cur_stream, pos, incr, 1);
3302 pos = get_master_clock(cur_stream);
3304 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3306 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3307 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3308 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3315 case SDL_MOUSEBUTTONDOWN:
3316 if (exit_on_mousedown) {
3317 do_exit(cur_stream);
3320 if (event.button.button == SDL_BUTTON_LEFT) {
3321 static int64_t last_mouse_left_click = 0;
3322 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3323 toggle_full_screen(cur_stream);
3324 cur_stream->force_refresh = 1;
3325 last_mouse_left_click = 0;
3327 last_mouse_left_click = av_gettime_relative();
3330 case SDL_MOUSEMOTION:
3331 if (cursor_hidden) {
3335 cursor_last_shown = av_gettime_relative();
3336 if (event.type == SDL_MOUSEBUTTONDOWN) {
3337 if (event.button.button != SDL_BUTTON_RIGHT)
3341 if (!(event.motion.state & SDL_BUTTON_RMASK))
3345 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3346 uint64_t size = avio_size(cur_stream->ic->pb);
3347 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3351 int tns, thh, tmm, tss;
3352 tns = cur_stream->ic->duration / 1000000LL;
3354 tmm = (tns % 3600) / 60;
3356 frac = x / cur_stream->width;
3359 mm = (ns % 3600) / 60;
3361 av_log(NULL, AV_LOG_INFO,
3362 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3363 hh, mm, ss, thh, tmm, tss);
3364 ts = frac * cur_stream->ic->duration;
3365 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3366 ts += cur_stream->ic->start_time;
3367 stream_seek(cur_stream, ts, 0, 0);
3370 case SDL_WINDOWEVENT:
3371 switch (event.window.event) {
3372 case SDL_WINDOWEVENT_RESIZED:
3373 screen_width = cur_stream->width = event.window.data1;
3374 screen_height = cur_stream->height = event.window.data2;
3375 if (cur_stream->vis_texture) {
3376 SDL_DestroyTexture(cur_stream->vis_texture);
3377 cur_stream->vis_texture = NULL;
3379 case SDL_WINDOWEVENT_EXPOSED:
3380 cur_stream->force_refresh = 1;
3385 do_exit(cur_stream);
3393 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3395 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3396 return opt_default(NULL, "video_size", arg);
3399 static int opt_width(void *optctx, const char *opt, const char *arg)
3401 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3405 static int opt_height(void *optctx, const char *opt, const char *arg)
3407 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3411 static int opt_format(void *optctx, const char *opt, const char *arg)
3413 file_iformat = av_find_input_format(arg);
3414 if (!file_iformat) {
3415 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3416 return AVERROR(EINVAL);
3421 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3423 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3424 return opt_default(NULL, "pixel_format", arg);
3427 static int opt_sync(void *optctx, const char *opt, const char *arg)
3429 if (!strcmp(arg, "audio"))
3430 av_sync_type = AV_SYNC_AUDIO_MASTER;
3431 else if (!strcmp(arg, "video"))
3432 av_sync_type = AV_SYNC_VIDEO_MASTER;
3433 else if (!strcmp(arg, "ext"))
3434 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3436 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3442 static int opt_seek(void *optctx, const char *opt, const char *arg)
3444 start_time = parse_time_or_die(opt, arg, 1);
3448 static int opt_duration(void *optctx, const char *opt, const char *arg)
3450 duration = parse_time_or_die(opt, arg, 1);
3454 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3456 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3457 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3458 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3459 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3463 static void opt_input_file(void *optctx, const char *filename)
3465 if (input_filename) {
3466 av_log(NULL, AV_LOG_FATAL,
3467 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3468 filename, input_filename);
3471 if (!strcmp(filename, "-"))
3473 input_filename = filename;
3476 static int opt_codec(void *optctx, const char *opt, const char *arg)
3478 const char *spec = strchr(opt, ':');
3480 av_log(NULL, AV_LOG_ERROR,
3481 "No media specifier was specified in '%s' in option '%s'\n",
3483 return AVERROR(EINVAL);
3487 case 'a' : audio_codec_name = arg; break;
3488 case 's' : subtitle_codec_name = arg; break;
3489 case 'v' : video_codec_name = arg; break;
3491 av_log(NULL, AV_LOG_ERROR,
3492 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3493 return AVERROR(EINVAL);
3500 static const OptionDef options[] = {
3501 #include "cmdutils_common_opts.h"
3502 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3503 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3504 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3505 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3506 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3507 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3508 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3509 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3510 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3511 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3512 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3513 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3514 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3515 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3516 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3517 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3518 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3519 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3520 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3521 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3522 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3523 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3524 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3525 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3526 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3527 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3528 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3529 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3530 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3531 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3533 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3534 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3536 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3537 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3538 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3539 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3540 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3541 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3542 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3543 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3544 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3548 static void show_usage(void)
3550 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3551 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3552 av_log(NULL, AV_LOG_INFO, "\n");
3555 void show_help_default(const char *opt, const char *arg)
3557 av_log_set_callback(log_callback_help);
3559 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3560 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3562 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3563 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3564 #if !CONFIG_AVFILTER
3565 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3567 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3569 printf("\nWhile playing:\n"
3571 "f toggle full screen\n"
3574 "9, 0 decrease and increase volume respectively\n"
3575 "/, * decrease and increase volume respectively\n"
3576 "a cycle audio channel in the current program\n"
3577 "v cycle video channel\n"
3578 "t cycle subtitle channel in the current program\n"
3580 "w cycle video filters or show modes\n"
3581 "s activate frame-step mode\n"
3582 "left/right seek backward/forward 10 seconds\n"
3583 "down/up seek backward/forward 1 minute\n"
3584 "page down/page up seek backward/forward 10 minutes\n"
3585 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3586 "left double-click toggle full screen\n"
3590 static int lockmgr(void **mtx, enum AVLockOp op)
3593 case AV_LOCK_CREATE:
3594 *mtx = SDL_CreateMutex();
3596 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3600 case AV_LOCK_OBTAIN:
3601 return !!SDL_LockMutex(*mtx);
3602 case AV_LOCK_RELEASE:
3603 return !!SDL_UnlockMutex(*mtx);
3604 case AV_LOCK_DESTROY:
3605 SDL_DestroyMutex(*mtx);
3611 /* Called from the main */
3612 int main(int argc, char **argv)
3619 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3620 parse_loglevel(argc, argv, options);
3622 /* register all codecs, demux and protocols */
3624 avdevice_register_all();
3627 avfilter_register_all();
3630 avformat_network_init();
3634 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3635 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3637 show_banner(argc, argv, options);
3639 parse_options(NULL, argc, argv, options, opt_input_file);
3641 if (!input_filename) {
3643 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3644 av_log(NULL, AV_LOG_FATAL,
3645 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3649 if (display_disable) {
3652 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3654 flags &= ~SDL_INIT_AUDIO;
3656 /* Try to work around an occasional ALSA buffer underflow issue when the
3657 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3658 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3659 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3661 if (display_disable)
3662 flags &= ~SDL_INIT_VIDEO;
3663 if (SDL_Init (flags)) {
3664 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3665 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3669 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3670 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3672 if (av_lockmgr_register(lockmgr)) {
3673 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3677 av_init_packet(&flush_pkt);
3678 flush_pkt.data = (uint8_t *)&flush_pkt;
3680 is = stream_open(input_filename, file_iformat);
3682 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");