2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
110 static unsigned sws_flags = SWS_BICUBIC;
112 typedef struct MyAVPacketList {
114 struct MyAVPacketList *next;
118 typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
129 #define VIDEO_PICTURE_QUEUE_SIZE 3
130 #define SUBPICTURE_QUEUE_SIZE 16
131 #define SAMPLE_QUEUE_SIZE 9
132 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
134 typedef struct AudioParams {
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
143 typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
148 int serial; /* clock is based on a packet with this serial */
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
153 /* Common struct for handling all types of decoded data and allocated render buffers. */
154 typedef struct Frame {
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
170 typedef struct FrameQueue {
171 Frame queue[FRAME_QUEUE_SIZE];
184 AV_SYNC_AUDIO_MASTER, /* default choice */
185 AV_SYNC_VIDEO_MASTER,
186 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
189 typedef struct Decoder {
193 AVCodecContext *avctx;
197 SDL_cond *empty_queue_cond;
199 AVRational start_pts_tb;
201 AVRational next_pts_tb;
202 SDL_Thread *decoder_tid;
205 typedef struct VideoState {
206 SDL_Thread *read_tid;
207 AVInputFormat *iformat;
212 int queue_attachments_req;
217 int read_pause_return;
241 int audio_clock_serial;
242 double audio_diff_cum; /* used for AV difference average computation */
243 double audio_diff_avg_coef;
244 double audio_diff_threshold;
245 int audio_diff_avg_count;
248 int audio_hw_buf_size;
251 unsigned int audio_buf_size; /* in bytes */
252 unsigned int audio_buf1_size;
253 int audio_buf_index; /* in bytes */
254 int audio_write_buf_size;
257 struct AudioParams audio_src;
259 struct AudioParams audio_filter_src;
261 struct AudioParams audio_tgt;
262 struct SwrContext *swr_ctx;
263 int frame_drops_early;
264 int frame_drops_late;
267 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
269 int16_t sample_array[SAMPLE_ARRAY_SIZE];
270 int sample_array_index;
274 FFTSample *rdft_data;
276 double last_vis_time;
277 SDL_Texture *vis_texture;
278 SDL_Texture *sub_texture;
281 AVStream *subtitle_st;
282 PacketQueue subtitleq;
285 double frame_last_returned_time;
286 double frame_last_filter_delay;
290 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
291 struct SwsContext *img_convert_ctx;
292 struct SwsContext *sub_convert_ctx;
296 int width, height, xleft, ytop;
301 AVFilterContext *in_video_filter; // the first filter in the video chain
302 AVFilterContext *out_video_filter; // the last filter in the video chain
303 AVFilterContext *in_audio_filter; // the first filter in the audio chain
304 AVFilterContext *out_audio_filter; // the last filter in the audio chain
305 AVFilterGraph *agraph; // audio filter graph
308 int last_video_stream, last_audio_stream, last_subtitle_stream;
310 SDL_cond *continue_read_thread;
313 /* options specified by the user */
314 static AVInputFormat *file_iformat;
315 static const char *input_filename;
316 static const char *window_title;
317 static int default_width = 640;
318 static int default_height = 480;
319 static int screen_width = 0;
320 static int screen_height = 0;
321 static int audio_disable;
322 static int video_disable;
323 static int subtitle_disable;
324 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
325 static int seek_by_bytes = -1;
326 static int display_disable;
327 static int show_status = 1;
328 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
329 static int64_t start_time = AV_NOPTS_VALUE;
330 static int64_t duration = AV_NOPTS_VALUE;
332 static int genpts = 0;
333 static int lowres = 0;
334 static int decoder_reorder_pts = -1;
336 static int exit_on_keydown;
337 static int exit_on_mousedown;
339 static int framedrop = -1;
340 static int infinite_buffer = -1;
341 static enum ShowMode show_mode = SHOW_MODE_NONE;
342 static const char *audio_codec_name;
343 static const char *subtitle_codec_name;
344 static const char *video_codec_name;
345 double rdftspeed = 0.02;
346 static int64_t cursor_last_shown;
347 static int cursor_hidden = 0;
349 static const char **vfilters_list = NULL;
350 static int nb_vfilters = 0;
351 static char *afilters = NULL;
353 static int autorotate = 1;
355 /* current context */
356 static int is_full_screen;
357 static int64_t audio_callback_time;
359 static AVPacket flush_pkt;
361 #define FF_ALLOC_EVENT (SDL_USEREVENT)
362 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
364 static SDL_Window *window;
365 static SDL_Renderer *renderer;
368 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
370 GROW_ARRAY(vfilters_list, nb_vfilters);
371 vfilters_list[nb_vfilters - 1] = arg;
377 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
378 enum AVSampleFormat fmt2, int64_t channel_count2)
380 /* If channel count == 1, planar and non-planar formats are the same */
381 if (channel_count1 == 1 && channel_count2 == 1)
382 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
384 return channel_count1 != channel_count2 || fmt1 != fmt2;
388 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
390 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
391 return channel_layout;
396 static void free_picture(Frame *vp);
398 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
400 MyAVPacketList *pkt1;
402 if (q->abort_request)
405 pkt1 = av_malloc(sizeof(MyAVPacketList));
410 if (pkt == &flush_pkt)
412 pkt1->serial = q->serial;
417 q->last_pkt->next = pkt1;
420 q->size += pkt1->pkt.size + sizeof(*pkt1);
421 q->duration += pkt1->pkt.duration;
422 /* XXX: should duplicate packet data in DV case */
423 SDL_CondSignal(q->cond);
427 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
431 SDL_LockMutex(q->mutex);
432 ret = packet_queue_put_private(q, pkt);
433 SDL_UnlockMutex(q->mutex);
435 if (pkt != &flush_pkt && ret < 0)
436 av_packet_unref(pkt);
441 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
443 AVPacket pkt1, *pkt = &pkt1;
447 pkt->stream_index = stream_index;
448 return packet_queue_put(q, pkt);
451 /* packet queue handling */
452 static int packet_queue_init(PacketQueue *q)
454 memset(q, 0, sizeof(PacketQueue));
455 q->mutex = SDL_CreateMutex();
457 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
458 return AVERROR(ENOMEM);
460 q->cond = SDL_CreateCond();
462 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
463 return AVERROR(ENOMEM);
465 q->abort_request = 1;
469 static void packet_queue_flush(PacketQueue *q)
471 MyAVPacketList *pkt, *pkt1;
473 SDL_LockMutex(q->mutex);
474 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
476 av_packet_unref(&pkt->pkt);
484 SDL_UnlockMutex(q->mutex);
487 static void packet_queue_destroy(PacketQueue *q)
489 packet_queue_flush(q);
490 SDL_DestroyMutex(q->mutex);
491 SDL_DestroyCond(q->cond);
494 static void packet_queue_abort(PacketQueue *q)
496 SDL_LockMutex(q->mutex);
498 q->abort_request = 1;
500 SDL_CondSignal(q->cond);
502 SDL_UnlockMutex(q->mutex);
505 static void packet_queue_start(PacketQueue *q)
507 SDL_LockMutex(q->mutex);
508 q->abort_request = 0;
509 packet_queue_put_private(q, &flush_pkt);
510 SDL_UnlockMutex(q->mutex);
513 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
514 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
516 MyAVPacketList *pkt1;
519 SDL_LockMutex(q->mutex);
522 if (q->abort_request) {
529 q->first_pkt = pkt1->next;
533 q->size -= pkt1->pkt.size + sizeof(*pkt1);
534 q->duration -= pkt1->pkt.duration;
537 *serial = pkt1->serial;
545 SDL_CondWait(q->cond, q->mutex);
548 SDL_UnlockMutex(q->mutex);
552 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
553 memset(d, 0, sizeof(Decoder));
556 d->empty_queue_cond = empty_queue_cond;
557 d->start_pts = AV_NOPTS_VALUE;
560 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
566 if (d->queue->abort_request)
569 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
572 if (d->queue->nb_packets == 0)
573 SDL_CondSignal(d->empty_queue_cond);
574 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
576 if (pkt.data == flush_pkt.data) {
577 avcodec_flush_buffers(d->avctx);
579 d->next_pts = d->start_pts;
580 d->next_pts_tb = d->start_pts_tb;
582 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
583 av_packet_unref(&d->pkt);
584 d->pkt_temp = d->pkt = pkt;
585 d->packet_pending = 1;
588 switch (d->avctx->codec_type) {
589 case AVMEDIA_TYPE_VIDEO:
590 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
592 if (decoder_reorder_pts == -1) {
593 frame->pts = av_frame_get_best_effort_timestamp(frame);
594 } else if (decoder_reorder_pts) {
595 frame->pts = frame->pkt_pts;
597 frame->pts = frame->pkt_dts;
601 case AVMEDIA_TYPE_AUDIO:
602 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
604 AVRational tb = (AVRational){1, frame->sample_rate};
605 if (frame->pts != AV_NOPTS_VALUE)
606 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
607 else if (frame->pkt_pts != AV_NOPTS_VALUE)
608 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
609 else if (d->next_pts != AV_NOPTS_VALUE)
610 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
611 if (frame->pts != AV_NOPTS_VALUE) {
612 d->next_pts = frame->pts + frame->nb_samples;
617 case AVMEDIA_TYPE_SUBTITLE:
618 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
623 d->packet_pending = 0;
626 d->pkt_temp.pts = AV_NOPTS_VALUE;
627 if (d->pkt_temp.data) {
628 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
629 ret = d->pkt_temp.size;
630 d->pkt_temp.data += ret;
631 d->pkt_temp.size -= ret;
632 if (d->pkt_temp.size <= 0)
633 d->packet_pending = 0;
636 d->packet_pending = 0;
637 d->finished = d->pkt_serial;
641 } while (!got_frame && !d->finished);
646 static void decoder_destroy(Decoder *d) {
647 av_packet_unref(&d->pkt);
648 avcodec_free_context(&d->avctx);
651 static void frame_queue_unref_item(Frame *vp)
653 av_frame_unref(vp->frame);
654 avsubtitle_free(&vp->sub);
657 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
660 memset(f, 0, sizeof(FrameQueue));
661 if (!(f->mutex = SDL_CreateMutex())) {
662 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
663 return AVERROR(ENOMEM);
665 if (!(f->cond = SDL_CreateCond())) {
666 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
667 return AVERROR(ENOMEM);
670 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
671 f->keep_last = !!keep_last;
672 for (i = 0; i < f->max_size; i++)
673 if (!(f->queue[i].frame = av_frame_alloc()))
674 return AVERROR(ENOMEM);
678 static void frame_queue_destory(FrameQueue *f)
681 for (i = 0; i < f->max_size; i++) {
682 Frame *vp = &f->queue[i];
683 frame_queue_unref_item(vp);
684 av_frame_free(&vp->frame);
687 SDL_DestroyMutex(f->mutex);
688 SDL_DestroyCond(f->cond);
691 static void frame_queue_signal(FrameQueue *f)
693 SDL_LockMutex(f->mutex);
694 SDL_CondSignal(f->cond);
695 SDL_UnlockMutex(f->mutex);
698 static Frame *frame_queue_peek(FrameQueue *f)
700 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
703 static Frame *frame_queue_peek_next(FrameQueue *f)
705 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
708 static Frame *frame_queue_peek_last(FrameQueue *f)
710 return &f->queue[f->rindex];
713 static Frame *frame_queue_peek_writable(FrameQueue *f)
715 /* wait until we have space to put a new frame */
716 SDL_LockMutex(f->mutex);
717 while (f->size >= f->max_size &&
718 !f->pktq->abort_request) {
719 SDL_CondWait(f->cond, f->mutex);
721 SDL_UnlockMutex(f->mutex);
723 if (f->pktq->abort_request)
726 return &f->queue[f->windex];
729 static Frame *frame_queue_peek_readable(FrameQueue *f)
731 /* wait until we have a readable a new frame */
732 SDL_LockMutex(f->mutex);
733 while (f->size - f->rindex_shown <= 0 &&
734 !f->pktq->abort_request) {
735 SDL_CondWait(f->cond, f->mutex);
737 SDL_UnlockMutex(f->mutex);
739 if (f->pktq->abort_request)
742 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
745 static void frame_queue_push(FrameQueue *f)
747 if (++f->windex == f->max_size)
749 SDL_LockMutex(f->mutex);
751 SDL_CondSignal(f->cond);
752 SDL_UnlockMutex(f->mutex);
755 static void frame_queue_next(FrameQueue *f)
757 if (f->keep_last && !f->rindex_shown) {
761 frame_queue_unref_item(&f->queue[f->rindex]);
762 if (++f->rindex == f->max_size)
764 SDL_LockMutex(f->mutex);
766 SDL_CondSignal(f->cond);
767 SDL_UnlockMutex(f->mutex);
770 /* return the number of undisplayed frames in the queue */
771 static int frame_queue_nb_remaining(FrameQueue *f)
773 return f->size - f->rindex_shown;
776 /* return last shown position */
777 static int64_t frame_queue_last_pos(FrameQueue *f)
779 Frame *fp = &f->queue[f->rindex];
780 if (f->rindex_shown && fp->serial == f->pktq->serial)
786 static void decoder_abort(Decoder *d, FrameQueue *fq)
788 packet_queue_abort(d->queue);
789 frame_queue_signal(fq);
790 SDL_WaitThread(d->decoder_tid, NULL);
791 d->decoder_tid = NULL;
792 packet_queue_flush(d->queue);
795 static inline void fill_rectangle(int x, int y, int w, int h)
803 SDL_RenderFillRect(renderer, &rect);
806 static void free_picture(Frame *vp)
809 SDL_DestroyTexture(vp->bmp);
814 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
818 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
821 SDL_DestroyTexture(*texture);
822 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
824 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
827 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
829 memset(pixels, 0, pitch * new_height);
830 SDL_UnlockTexture(*texture);
836 static void calculate_display_rect(SDL_Rect *rect,
837 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
838 int pic_width, int pic_height, AVRational pic_sar)
841 int width, height, x, y;
843 if (pic_sar.num == 0)
846 aspect_ratio = av_q2d(pic_sar);
848 if (aspect_ratio <= 0.0)
850 aspect_ratio *= (float)pic_width / (float)pic_height;
852 /* XXX: we suppose the screen has a 1.0 pixel ratio */
854 width = lrint(height * aspect_ratio) & ~1;
855 if (width > scr_width) {
857 height = lrint(width / aspect_ratio) & ~1;
859 x = (scr_width - width) / 2;
860 y = (scr_height - height) / 2;
861 rect->x = scr_xleft + x;
862 rect->y = scr_ytop + y;
863 rect->w = FFMAX(width, 1);
864 rect->h = FFMAX(height, 1);
867 static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
869 switch (frame->format) {
870 case AV_PIX_FMT_YUV420P:
871 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
872 frame->data[1], frame->linesize[1],
873 frame->data[2], frame->linesize[2]);
875 case AV_PIX_FMT_BGRA:
876 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
879 /* This should only happen if we are not using avfilter... */
880 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
881 frame->width, frame->height, frame->format, frame->width, frame->height,
882 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
883 if (*img_convert_ctx != NULL) {
886 if (!SDL_LockTexture(tex, NULL, (void **)&pixels, &pitch)) {
887 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
888 0, frame->height, &pixels, &pitch);
889 SDL_UnlockTexture(tex);
892 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
900 static void video_image_display(VideoState *is)
906 vp = frame_queue_peek_last(&is->pictq);
908 if (is->subtitle_st) {
909 if (frame_queue_nb_remaining(&is->subpq) > 0) {
910 sp = frame_queue_peek(&is->subpq);
912 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
917 if (!sp->width || !sp->height) {
918 sp->width = vp->width;
919 sp->height = vp->height;
921 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
924 for (i = 0; i < sp->sub.num_rects; i++) {
925 AVSubtitleRect *sub_rect = sp->sub.rects[i];
927 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
928 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
929 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
930 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
932 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
933 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
934 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
935 0, NULL, NULL, NULL);
936 if (!is->sub_convert_ctx) {
937 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
940 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
941 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
942 0, sub_rect->h, &pixels, &pitch);
943 SDL_UnlockTexture(is->sub_texture);
953 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
956 if (upload_texture(vp->bmp, vp->frame, &is->img_convert_ctx) < 0)
961 SDL_RenderCopy(renderer, vp->bmp, NULL, &rect);
963 #if USE_ONEPASS_SUBTITLE_RENDER
964 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
967 double xratio = (double)rect.w / (double)sp->width;
968 double yratio = (double)rect.h / (double)sp->height;
969 for (i = 0; i < sp->sub.num_rects; i++) {
970 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
971 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
972 .y = rect.y + sub_rect->y * yratio,
973 .w = sub_rect->w * xratio,
974 .h = sub_rect->h * yratio};
975 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
982 static inline int compute_mod(int a, int b)
984 return a < 0 ? a%b + b : a%b;
987 static void video_audio_display(VideoState *s)
989 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
990 int ch, channels, h, h2;
992 int rdft_bits, nb_freq;
994 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
996 nb_freq = 1 << (rdft_bits - 1);
998 /* compute display index : center on currently output samples */
999 channels = s->audio_tgt.channels;
1000 nb_display_channels = channels;
1002 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1004 delay = s->audio_write_buf_size;
1007 /* to be more precise, we take into account the time spent since
1008 the last buffer computation */
1009 if (audio_callback_time) {
1010 time_diff = av_gettime_relative() - audio_callback_time;
1011 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1014 delay += 2 * data_used;
1015 if (delay < data_used)
1018 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1019 if (s->show_mode == SHOW_MODE_WAVES) {
1021 for (i = 0; i < 1000; i += channels) {
1022 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1023 int a = s->sample_array[idx];
1024 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1025 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1026 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1028 if (h < score && (b ^ c) < 0) {
1035 s->last_i_start = i_start;
1037 i_start = s->last_i_start;
1040 if (s->show_mode == SHOW_MODE_WAVES) {
1041 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1043 /* total height for one channel */
1044 h = s->height / nb_display_channels;
1045 /* graph height / 2 */
1047 for (ch = 0; ch < nb_display_channels; ch++) {
1049 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1050 for (x = 0; x < s->width; x++) {
1051 y = (s->sample_array[i] * h2) >> 15;
1058 fill_rectangle(s->xleft + x, ys, 1, y);
1060 if (i >= SAMPLE_ARRAY_SIZE)
1061 i -= SAMPLE_ARRAY_SIZE;
1065 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1067 for (ch = 1; ch < nb_display_channels; ch++) {
1068 y = s->ytop + ch * h;
1069 fill_rectangle(s->xleft, y, s->width, 1);
1072 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1075 nb_display_channels= FFMIN(nb_display_channels, 2);
1076 if (rdft_bits != s->rdft_bits) {
1077 av_rdft_end(s->rdft);
1078 av_free(s->rdft_data);
1079 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1080 s->rdft_bits = rdft_bits;
1081 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1083 if (!s->rdft || !s->rdft_data){
1084 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1085 s->show_mode = SHOW_MODE_WAVES;
1088 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1091 for (ch = 0; ch < nb_display_channels; ch++) {
1092 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1094 for (x = 0; x < 2 * nb_freq; x++) {
1095 double w = (x-nb_freq) * (1.0 / nb_freq);
1096 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1098 if (i >= SAMPLE_ARRAY_SIZE)
1099 i -= SAMPLE_ARRAY_SIZE;
1101 av_rdft_calc(s->rdft, data[ch]);
1103 /* Least efficient way to do this, we should of course
1104 * directly access it but it is more than fast enough. */
1105 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1107 pixels += pitch * s->height;
1108 for (y = 0; y < s->height; y++) {
1109 double w = 1 / sqrt(nb_freq);
1110 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
1111 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1116 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1118 SDL_UnlockTexture(s->vis_texture);
1120 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1124 if (s->xpos >= s->width)
1129 static void stream_component_close(VideoState *is, int stream_index)
1131 AVFormatContext *ic = is->ic;
1132 AVCodecParameters *codecpar;
1134 if (stream_index < 0 || stream_index >= ic->nb_streams)
1136 codecpar = ic->streams[stream_index]->codecpar;
1138 switch (codecpar->codec_type) {
1139 case AVMEDIA_TYPE_AUDIO:
1140 decoder_abort(&is->auddec, &is->sampq);
1142 decoder_destroy(&is->auddec);
1143 swr_free(&is->swr_ctx);
1144 av_freep(&is->audio_buf1);
1145 is->audio_buf1_size = 0;
1146 is->audio_buf = NULL;
1149 av_rdft_end(is->rdft);
1150 av_freep(&is->rdft_data);
1155 case AVMEDIA_TYPE_VIDEO:
1156 decoder_abort(&is->viddec, &is->pictq);
1157 decoder_destroy(&is->viddec);
1159 case AVMEDIA_TYPE_SUBTITLE:
1160 decoder_abort(&is->subdec, &is->subpq);
1161 decoder_destroy(&is->subdec);
1167 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1168 switch (codecpar->codec_type) {
1169 case AVMEDIA_TYPE_AUDIO:
1170 is->audio_st = NULL;
1171 is->audio_stream = -1;
1173 case AVMEDIA_TYPE_VIDEO:
1174 is->video_st = NULL;
1175 is->video_stream = -1;
1177 case AVMEDIA_TYPE_SUBTITLE:
1178 is->subtitle_st = NULL;
1179 is->subtitle_stream = -1;
1186 static void stream_close(VideoState *is)
1188 /* XXX: use a special url_shutdown call to abort parse cleanly */
1189 is->abort_request = 1;
1190 SDL_WaitThread(is->read_tid, NULL);
1192 /* close each stream */
1193 if (is->audio_stream >= 0)
1194 stream_component_close(is, is->audio_stream);
1195 if (is->video_stream >= 0)
1196 stream_component_close(is, is->video_stream);
1197 if (is->subtitle_stream >= 0)
1198 stream_component_close(is, is->subtitle_stream);
1200 avformat_close_input(&is->ic);
1202 packet_queue_destroy(&is->videoq);
1203 packet_queue_destroy(&is->audioq);
1204 packet_queue_destroy(&is->subtitleq);
1206 /* free all pictures */
1207 frame_queue_destory(&is->pictq);
1208 frame_queue_destory(&is->sampq);
1209 frame_queue_destory(&is->subpq);
1210 SDL_DestroyCond(is->continue_read_thread);
1211 sws_freeContext(is->img_convert_ctx);
1212 sws_freeContext(is->sub_convert_ctx);
1213 av_free(is->filename);
1214 if (is->vis_texture)
1215 SDL_DestroyTexture(is->vis_texture);
1216 if (is->sub_texture)
1217 SDL_DestroyTexture(is->sub_texture);
1221 static void do_exit(VideoState *is)
1227 SDL_DestroyRenderer(renderer);
1229 SDL_DestroyWindow(window);
1230 av_lockmgr_register(NULL);
1233 av_freep(&vfilters_list);
1235 avformat_network_deinit();
1239 av_log(NULL, AV_LOG_QUIET, "%s", "");
1243 static void sigterm_handler(int sig)
1248 static void set_default_window_size(int width, int height, AVRational sar)
1251 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1252 default_width = rect.w;
1253 default_height = rect.h;
1256 static int video_open(VideoState *is, Frame *vp)
1260 if (vp && vp->width)
1261 set_default_window_size(vp->width, vp->height, vp->sar);
1272 int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
1274 window_title = input_filename;
1276 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1277 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1278 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1280 SDL_RendererInfo info;
1281 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1283 if (!SDL_GetRendererInfo(renderer, &info))
1284 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1288 SDL_SetWindowSize(window, w, h);
1291 if (!window || !renderer) {
1292 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1302 /* display the current picture, if any */
1303 static void video_display(VideoState *is)
1306 video_open(is, NULL);
1308 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1309 SDL_RenderClear(renderer);
1310 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1311 video_audio_display(is);
1312 else if (is->video_st)
1313 video_image_display(is);
1314 SDL_RenderPresent(renderer);
1317 static double get_clock(Clock *c)
1319 if (*c->queue_serial != c->serial)
1324 double time = av_gettime_relative() / 1000000.0;
1325 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1329 static void set_clock_at(Clock *c, double pts, int serial, double time)
1332 c->last_updated = time;
1333 c->pts_drift = c->pts - time;
1337 static void set_clock(Clock *c, double pts, int serial)
1339 double time = av_gettime_relative() / 1000000.0;
1340 set_clock_at(c, pts, serial, time);
1343 static void set_clock_speed(Clock *c, double speed)
1345 set_clock(c, get_clock(c), c->serial);
1349 static void init_clock(Clock *c, int *queue_serial)
1353 c->queue_serial = queue_serial;
1354 set_clock(c, NAN, -1);
1357 static void sync_clock_to_slave(Clock *c, Clock *slave)
1359 double clock = get_clock(c);
1360 double slave_clock = get_clock(slave);
1361 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1362 set_clock(c, slave_clock, slave->serial);
1365 static int get_master_sync_type(VideoState *is) {
1366 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1368 return AV_SYNC_VIDEO_MASTER;
1370 return AV_SYNC_AUDIO_MASTER;
1371 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1373 return AV_SYNC_AUDIO_MASTER;
1375 return AV_SYNC_EXTERNAL_CLOCK;
1377 return AV_SYNC_EXTERNAL_CLOCK;
1381 /* get the current master clock value */
1382 static double get_master_clock(VideoState *is)
1386 switch (get_master_sync_type(is)) {
1387 case AV_SYNC_VIDEO_MASTER:
1388 val = get_clock(&is->vidclk);
1390 case AV_SYNC_AUDIO_MASTER:
1391 val = get_clock(&is->audclk);
1394 val = get_clock(&is->extclk);
1400 static void check_external_clock_speed(VideoState *is) {
1401 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1402 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1403 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1404 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1405 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1406 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1408 double speed = is->extclk.speed;
1410 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1414 /* seek in the stream */
1415 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1417 if (!is->seek_req) {
1420 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1422 is->seek_flags |= AVSEEK_FLAG_BYTE;
1424 SDL_CondSignal(is->continue_read_thread);
1428 /* pause or resume the video */
1429 static void stream_toggle_pause(VideoState *is)
1432 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1433 if (is->read_pause_return != AVERROR(ENOSYS)) {
1434 is->vidclk.paused = 0;
1436 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1438 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1439 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1442 static void toggle_pause(VideoState *is)
1444 stream_toggle_pause(is);
1448 static void toggle_mute(VideoState *is)
1450 is->muted = !is->muted;
1453 static void update_volume(VideoState *is, int sign, int step)
1455 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1458 static void step_to_next_frame(VideoState *is)
1460 /* if the stream is paused unpause it, then step */
1462 stream_toggle_pause(is);
1466 static double compute_target_delay(double delay, VideoState *is)
1468 double sync_threshold, diff = 0;
1470 /* update delay to follow master synchronisation source */
1471 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1472 /* if video is slave, we try to correct big delays by
1473 duplicating or deleting a frame */
1474 diff = get_clock(&is->vidclk) - get_master_clock(is);
1476 /* skip or repeat frame. We take into account the
1477 delay to compute the threshold. I still don't know
1478 if it is the best guess */
1479 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1480 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1481 if (diff <= -sync_threshold)
1482 delay = FFMAX(0, delay + diff);
1483 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1484 delay = delay + diff;
1485 else if (diff >= sync_threshold)
1490 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1496 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1497 if (vp->serial == nextvp->serial) {
1498 double duration = nextvp->pts - vp->pts;
1499 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1500 return vp->duration;
1508 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1509 /* update current video pts */
1510 set_clock(&is->vidclk, pts, serial);
1511 sync_clock_to_slave(&is->extclk, &is->vidclk);
1514 /* called to display each frame */
1515 static void video_refresh(void *opaque, double *remaining_time)
1517 VideoState *is = opaque;
1522 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1523 check_external_clock_speed(is);
1525 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1526 time = av_gettime_relative() / 1000000.0;
1527 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1529 is->last_vis_time = time;
1531 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1536 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1537 // nothing to do, no picture to display in the queue
1539 double last_duration, duration, delay;
1542 /* dequeue the picture */
1543 lastvp = frame_queue_peek_last(&is->pictq);
1544 vp = frame_queue_peek(&is->pictq);
1546 if (vp->serial != is->videoq.serial) {
1547 frame_queue_next(&is->pictq);
1551 if (lastvp->serial != vp->serial)
1552 is->frame_timer = av_gettime_relative() / 1000000.0;
1557 /* compute nominal last_duration */
1558 last_duration = vp_duration(is, lastvp, vp);
1559 delay = compute_target_delay(last_duration, is);
1561 time= av_gettime_relative()/1000000.0;
1562 if (time < is->frame_timer + delay) {
1563 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1567 is->frame_timer += delay;
1568 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1569 is->frame_timer = time;
1571 SDL_LockMutex(is->pictq.mutex);
1572 if (!isnan(vp->pts))
1573 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1574 SDL_UnlockMutex(is->pictq.mutex);
1576 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1577 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1578 duration = vp_duration(is, vp, nextvp);
1579 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1580 is->frame_drops_late++;
1581 frame_queue_next(&is->pictq);
1586 if (is->subtitle_st) {
1587 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1588 sp = frame_queue_peek(&is->subpq);
1590 if (frame_queue_nb_remaining(&is->subpq) > 1)
1591 sp2 = frame_queue_peek_next(&is->subpq);
1595 if (sp->serial != is->subtitleq.serial
1596 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1597 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1601 for (i = 0; i < sp->sub.num_rects; i++) {
1602 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1606 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1607 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1608 memset(pixels, 0, sub_rect->w << 2);
1609 SDL_UnlockTexture(is->sub_texture);
1613 frame_queue_next(&is->subpq);
1620 frame_queue_next(&is->pictq);
1621 is->force_refresh = 1;
1623 if (is->step && !is->paused)
1624 stream_toggle_pause(is);
1627 /* display picture */
1628 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1631 is->force_refresh = 0;
1633 static int64_t last_time;
1635 int aqsize, vqsize, sqsize;
1638 cur_time = av_gettime_relative();
1639 if (!last_time || (cur_time - last_time) >= 30000) {
1644 aqsize = is->audioq.size;
1646 vqsize = is->videoq.size;
1647 if (is->subtitle_st)
1648 sqsize = is->subtitleq.size;
1650 if (is->audio_st && is->video_st)
1651 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1652 else if (is->video_st)
1653 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1654 else if (is->audio_st)
1655 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1656 av_log(NULL, AV_LOG_INFO,
1657 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1658 get_master_clock(is),
1659 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1661 is->frame_drops_early + is->frame_drops_late,
1665 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1666 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1668 last_time = cur_time;
1673 /* allocate a picture (needs to do that in main thread to avoid
1674 potential locking problems */
1675 static void alloc_picture(VideoState *is)
1680 vp = &is->pictq.queue[is->pictq.windex];
1684 if (vp->format == AV_PIX_FMT_YUV420P)
1685 sdl_format = SDL_PIXELFORMAT_YV12;
1687 sdl_format = SDL_PIXELFORMAT_ARGB8888;
1689 if (realloc_texture(&vp->bmp, sdl_format, vp->width, vp->height, SDL_BLENDMODE_NONE, 0) < 0) {
1690 /* SDL allocates a buffer smaller than requested if the video
1691 * overlay hardware is unable to support the requested size. */
1692 av_log(NULL, AV_LOG_FATAL,
1693 "Error: the video system does not support an image\n"
1694 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1695 "to reduce the image size.\n", vp->width, vp->height );
1699 SDL_LockMutex(is->pictq.mutex);
1701 SDL_CondSignal(is->pictq.cond);
1702 SDL_UnlockMutex(is->pictq.mutex);
1705 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1709 #if defined(DEBUG_SYNC)
1710 printf("frame_type=%c pts=%0.3f\n",
1711 av_get_picture_type_char(src_frame->pict_type), pts);
1714 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1717 vp->sar = src_frame->sample_aspect_ratio;
1720 /* alloc or resize hardware picture buffer */
1721 if (!vp->bmp || !vp->allocated ||
1722 vp->width != src_frame->width ||
1723 vp->height != src_frame->height ||
1724 vp->format != src_frame->format) {
1728 vp->width = src_frame->width;
1729 vp->height = src_frame->height;
1730 vp->format = src_frame->format;
1732 /* the allocation must be done in the main thread to avoid
1733 locking problems. */
1734 event.type = FF_ALLOC_EVENT;
1735 event.user.data1 = is;
1736 SDL_PushEvent(&event);
1738 /* wait until the picture is allocated */
1739 SDL_LockMutex(is->pictq.mutex);
1740 while (!vp->allocated && !is->videoq.abort_request) {
1741 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1743 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1744 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, FF_ALLOC_EVENT, FF_ALLOC_EVENT) != 1) {
1745 while (!vp->allocated && !is->abort_request) {
1746 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1749 SDL_UnlockMutex(is->pictq.mutex);
1751 if (is->videoq.abort_request)
1755 /* if the frame is not skipped, then display it */
1758 vp->duration = duration;
1760 vp->serial = serial;
1762 av_frame_move_ref(vp->frame, src_frame);
1763 frame_queue_push(&is->pictq);
1768 static int get_video_frame(VideoState *is, AVFrame *frame)
1772 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1778 if (frame->pts != AV_NOPTS_VALUE)
1779 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1781 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1783 is->viddec_width = frame->width;
1784 is->viddec_height = frame->height;
1786 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1787 if (frame->pts != AV_NOPTS_VALUE) {
1788 double diff = dpts - get_master_clock(is);
1789 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1790 diff - is->frame_last_filter_delay < 0 &&
1791 is->viddec.pkt_serial == is->vidclk.serial &&
1792 is->videoq.nb_packets) {
1793 is->frame_drops_early++;
1794 av_frame_unref(frame);
1805 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1806 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1809 int nb_filters = graph->nb_filters;
1810 AVFilterInOut *outputs = NULL, *inputs = NULL;
1813 outputs = avfilter_inout_alloc();
1814 inputs = avfilter_inout_alloc();
1815 if (!outputs || !inputs) {
1816 ret = AVERROR(ENOMEM);
1820 outputs->name = av_strdup("in");
1821 outputs->filter_ctx = source_ctx;
1822 outputs->pad_idx = 0;
1823 outputs->next = NULL;
1825 inputs->name = av_strdup("out");
1826 inputs->filter_ctx = sink_ctx;
1827 inputs->pad_idx = 0;
1828 inputs->next = NULL;
1830 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1833 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1837 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1838 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1839 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1841 ret = avfilter_graph_config(graph, NULL);
1843 avfilter_inout_free(&outputs);
1844 avfilter_inout_free(&inputs);
1848 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1850 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1851 char sws_flags_str[512] = "";
1852 char buffersrc_args[256];
1854 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1855 AVCodecParameters *codecpar = is->video_st->codecpar;
1856 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1857 AVDictionaryEntry *e = NULL;
1859 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1860 if (!strcmp(e->key, "sws_flags")) {
1861 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1863 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1865 if (strlen(sws_flags_str))
1866 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1868 graph->scale_sws_opts = av_strdup(sws_flags_str);
1870 snprintf(buffersrc_args, sizeof(buffersrc_args),
1871 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1872 frame->width, frame->height, frame->format,
1873 is->video_st->time_base.num, is->video_st->time_base.den,
1874 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1875 if (fr.num && fr.den)
1876 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1878 if ((ret = avfilter_graph_create_filter(&filt_src,
1879 avfilter_get_by_name("buffer"),
1880 "ffplay_buffer", buffersrc_args, NULL,
1884 ret = avfilter_graph_create_filter(&filt_out,
1885 avfilter_get_by_name("buffersink"),
1886 "ffplay_buffersink", NULL, NULL, graph);
1890 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1893 last_filter = filt_out;
1895 /* Note: this macro adds a filter before the lastly added filter, so the
1896 * processing order of the filters is in reverse */
1897 #define INSERT_FILT(name, arg) do { \
1898 AVFilterContext *filt_ctx; \
1900 ret = avfilter_graph_create_filter(&filt_ctx, \
1901 avfilter_get_by_name(name), \
1902 "ffplay_" name, arg, NULL, graph); \
1906 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1910 last_filter = filt_ctx; \
1914 double theta = get_rotation(is->video_st);
1916 if (fabs(theta - 90) < 1.0) {
1917 INSERT_FILT("transpose", "clock");
1918 } else if (fabs(theta - 180) < 1.0) {
1919 INSERT_FILT("hflip", NULL);
1920 INSERT_FILT("vflip", NULL);
1921 } else if (fabs(theta - 270) < 1.0) {
1922 INSERT_FILT("transpose", "cclock");
1923 } else if (fabs(theta) > 1.0) {
1924 char rotate_buf[64];
1925 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1926 INSERT_FILT("rotate", rotate_buf);
1930 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1933 is->in_video_filter = filt_src;
1934 is->out_video_filter = filt_out;
1940 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1942 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1943 int sample_rates[2] = { 0, -1 };
1944 int64_t channel_layouts[2] = { 0, -1 };
1945 int channels[2] = { 0, -1 };
1946 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1947 char aresample_swr_opts[512] = "";
1948 AVDictionaryEntry *e = NULL;
1949 char asrc_args[256];
1952 avfilter_graph_free(&is->agraph);
1953 if (!(is->agraph = avfilter_graph_alloc()))
1954 return AVERROR(ENOMEM);
1956 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1957 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1958 if (strlen(aresample_swr_opts))
1959 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1960 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1962 ret = snprintf(asrc_args, sizeof(asrc_args),
1963 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1964 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1965 is->audio_filter_src.channels,
1966 1, is->audio_filter_src.freq);
1967 if (is->audio_filter_src.channel_layout)
1968 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1969 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1971 ret = avfilter_graph_create_filter(&filt_asrc,
1972 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1973 asrc_args, NULL, is->agraph);
1978 ret = avfilter_graph_create_filter(&filt_asink,
1979 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1980 NULL, NULL, is->agraph);
1984 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1986 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1989 if (force_output_format) {
1990 channel_layouts[0] = is->audio_tgt.channel_layout;
1991 channels [0] = is->audio_tgt.channels;
1992 sample_rates [0] = is->audio_tgt.freq;
1993 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1995 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1997 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1999 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2004 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2007 is->in_audio_filter = filt_asrc;
2008 is->out_audio_filter = filt_asink;
2012 avfilter_graph_free(&is->agraph);
2015 #endif /* CONFIG_AVFILTER */
2017 static int audio_thread(void *arg)
2019 VideoState *is = arg;
2020 AVFrame *frame = av_frame_alloc();
2023 int last_serial = -1;
2024 int64_t dec_channel_layout;
2032 return AVERROR(ENOMEM);
2035 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2039 tb = (AVRational){1, frame->sample_rate};
2042 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2045 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2046 frame->format, av_frame_get_channels(frame)) ||
2047 is->audio_filter_src.channel_layout != dec_channel_layout ||
2048 is->audio_filter_src.freq != frame->sample_rate ||
2049 is->auddec.pkt_serial != last_serial;
2052 char buf1[1024], buf2[1024];
2053 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2054 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2055 av_log(NULL, AV_LOG_DEBUG,
2056 "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",
2057 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2058 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2060 is->audio_filter_src.fmt = frame->format;
2061 is->audio_filter_src.channels = av_frame_get_channels(frame);
2062 is->audio_filter_src.channel_layout = dec_channel_layout;
2063 is->audio_filter_src.freq = frame->sample_rate;
2064 last_serial = is->auddec.pkt_serial;
2066 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2070 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2073 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2074 tb = is->out_audio_filter->inputs[0]->time_base;
2076 if (!(af = frame_queue_peek_writable(&is->sampq)))
2079 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2080 af->pos = av_frame_get_pkt_pos(frame);
2081 af->serial = is->auddec.pkt_serial;
2082 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2084 av_frame_move_ref(af->frame, frame);
2085 frame_queue_push(&is->sampq);
2088 if (is->audioq.serial != is->auddec.pkt_serial)
2091 if (ret == AVERROR_EOF)
2092 is->auddec.finished = is->auddec.pkt_serial;
2095 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2098 avfilter_graph_free(&is->agraph);
2100 av_frame_free(&frame);
2104 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2106 packet_queue_start(d->queue);
2107 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2108 if (!d->decoder_tid) {
2109 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2110 return AVERROR(ENOMEM);
2115 static int video_thread(void *arg)
2117 VideoState *is = arg;
2118 AVFrame *frame = av_frame_alloc();
2122 AVRational tb = is->video_st->time_base;
2123 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2126 AVFilterGraph *graph = avfilter_graph_alloc();
2127 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2130 enum AVPixelFormat last_format = -2;
2131 int last_serial = -1;
2132 int last_vfilter_idx = 0;
2134 av_frame_free(&frame);
2135 return AVERROR(ENOMEM);
2142 avfilter_graph_free(&graph);
2144 return AVERROR(ENOMEM);
2148 ret = get_video_frame(is, frame);
2155 if ( last_w != frame->width
2156 || last_h != frame->height
2157 || last_format != frame->format
2158 || last_serial != is->viddec.pkt_serial
2159 || last_vfilter_idx != is->vfilter_idx) {
2160 av_log(NULL, AV_LOG_DEBUG,
2161 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2163 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2164 frame->width, frame->height,
2165 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2166 avfilter_graph_free(&graph);
2167 graph = avfilter_graph_alloc();
2168 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2170 event.type = FF_QUIT_EVENT;
2171 event.user.data1 = is;
2172 SDL_PushEvent(&event);
2175 filt_in = is->in_video_filter;
2176 filt_out = is->out_video_filter;
2177 last_w = frame->width;
2178 last_h = frame->height;
2179 last_format = frame->format;
2180 last_serial = is->viddec.pkt_serial;
2181 last_vfilter_idx = is->vfilter_idx;
2182 frame_rate = filt_out->inputs[0]->frame_rate;
2185 ret = av_buffersrc_add_frame(filt_in, frame);
2190 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2192 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2194 if (ret == AVERROR_EOF)
2195 is->viddec.finished = is->viddec.pkt_serial;
2200 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2201 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2202 is->frame_last_filter_delay = 0;
2203 tb = filt_out->inputs[0]->time_base;
2205 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2206 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2207 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2208 av_frame_unref(frame);
2218 avfilter_graph_free(&graph);
2220 av_frame_free(&frame);
2224 static int subtitle_thread(void *arg)
2226 VideoState *is = arg;
2227 AVCodecParameters *codecpar = is->subtitle_st->codecpar;
2233 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2236 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2241 if (got_subtitle && sp->sub.format == 0) {
2242 if (sp->sub.pts != AV_NOPTS_VALUE)
2243 pts = sp->sub.pts / (double)AV_TIME_BASE;
2245 sp->serial = is->subdec.pkt_serial;
2246 sp->width = codecpar->width;
2247 sp->height = codecpar->height;
2250 /* now we can update the picture count */
2251 frame_queue_push(&is->subpq);
2252 } else if (got_subtitle) {
2253 avsubtitle_free(&sp->sub);
2259 /* copy samples for viewing in editor window */
2260 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2264 size = samples_size / sizeof(short);
2266 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2269 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2271 is->sample_array_index += len;
2272 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2273 is->sample_array_index = 0;
2278 /* return the wanted number of samples to get better sync if sync_type is video
2279 * or external master clock */
2280 static int synchronize_audio(VideoState *is, int nb_samples)
2282 int wanted_nb_samples = nb_samples;
2284 /* if not master, then we try to remove or add samples to correct the clock */
2285 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2286 double diff, avg_diff;
2287 int min_nb_samples, max_nb_samples;
2289 diff = get_clock(&is->audclk) - get_master_clock(is);
2291 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2292 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2293 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2294 /* not enough measures to have a correct estimate */
2295 is->audio_diff_avg_count++;
2297 /* estimate the A-V difference */
2298 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2300 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2301 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2302 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2303 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2304 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2306 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2307 diff, avg_diff, wanted_nb_samples - nb_samples,
2308 is->audio_clock, is->audio_diff_threshold);
2311 /* too big difference : may be initial PTS errors, so
2313 is->audio_diff_avg_count = 0;
2314 is->audio_diff_cum = 0;
2318 return wanted_nb_samples;
2322 * Decode one audio frame and return its uncompressed size.
2324 * The processed audio frame is decoded, converted if required, and
2325 * stored in is->audio_buf, with size in bytes given by the return
2328 static int audio_decode_frame(VideoState *is)
2330 int data_size, resampled_data_size;
2331 int64_t dec_channel_layout;
2332 av_unused double audio_clock0;
2333 int wanted_nb_samples;
2341 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2342 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2347 if (!(af = frame_queue_peek_readable(&is->sampq)))
2349 frame_queue_next(&is->sampq);
2350 } while (af->serial != is->audioq.serial);
2352 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2353 af->frame->nb_samples,
2354 af->frame->format, 1);
2356 dec_channel_layout =
2357 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2358 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2359 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2361 if (af->frame->format != is->audio_src.fmt ||
2362 dec_channel_layout != is->audio_src.channel_layout ||
2363 af->frame->sample_rate != is->audio_src.freq ||
2364 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2365 swr_free(&is->swr_ctx);
2366 is->swr_ctx = swr_alloc_set_opts(NULL,
2367 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2368 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2370 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2371 av_log(NULL, AV_LOG_ERROR,
2372 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2373 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2374 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2375 swr_free(&is->swr_ctx);
2378 is->audio_src.channel_layout = dec_channel_layout;
2379 is->audio_src.channels = av_frame_get_channels(af->frame);
2380 is->audio_src.freq = af->frame->sample_rate;
2381 is->audio_src.fmt = af->frame->format;
2385 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2386 uint8_t **out = &is->audio_buf1;
2387 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2388 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2391 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2394 if (wanted_nb_samples != af->frame->nb_samples) {
2395 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2396 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2397 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2401 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2402 if (!is->audio_buf1)
2403 return AVERROR(ENOMEM);
2404 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2406 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2409 if (len2 == out_count) {
2410 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2411 if (swr_init(is->swr_ctx) < 0)
2412 swr_free(&is->swr_ctx);
2414 is->audio_buf = is->audio_buf1;
2415 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2417 is->audio_buf = af->frame->data[0];
2418 resampled_data_size = data_size;
2421 audio_clock0 = is->audio_clock;
2422 /* update the audio clock with the pts */
2423 if (!isnan(af->pts))
2424 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2426 is->audio_clock = NAN;
2427 is->audio_clock_serial = af->serial;
2430 static double last_clock;
2431 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2432 is->audio_clock - last_clock,
2433 is->audio_clock, audio_clock0);
2434 last_clock = is->audio_clock;
2437 return resampled_data_size;
2440 /* prepare a new audio buffer */
2441 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2443 VideoState *is = opaque;
2444 int audio_size, len1;
2446 audio_callback_time = av_gettime_relative();
2449 if (is->audio_buf_index >= is->audio_buf_size) {
2450 audio_size = audio_decode_frame(is);
2451 if (audio_size < 0) {
2452 /* if error, just output silence */
2453 is->audio_buf = NULL;
2454 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2456 if (is->show_mode != SHOW_MODE_VIDEO)
2457 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2458 is->audio_buf_size = audio_size;
2460 is->audio_buf_index = 0;
2462 len1 = is->audio_buf_size - is->audio_buf_index;
2465 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2466 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2468 memset(stream, 0, len1);
2469 if (!is->muted && is->audio_buf)
2470 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2474 is->audio_buf_index += len1;
2476 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2477 /* Let's assume the audio driver that is used by SDL has two periods. */
2478 if (!isnan(is->audio_clock)) {
2479 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);
2480 sync_clock_to_slave(&is->extclk, &is->audclk);
2484 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2486 SDL_AudioSpec wanted_spec, spec;
2488 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2489 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2490 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2492 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2494 wanted_nb_channels = atoi(env);
2495 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2497 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2498 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2499 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2501 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2502 wanted_spec.channels = wanted_nb_channels;
2503 wanted_spec.freq = wanted_sample_rate;
2504 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2505 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2508 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2509 next_sample_rate_idx--;
2510 wanted_spec.format = AUDIO_S16SYS;
2511 wanted_spec.silence = 0;
2512 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2513 wanted_spec.callback = sdl_audio_callback;
2514 wanted_spec.userdata = opaque;
2515 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2516 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2517 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2518 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2519 if (!wanted_spec.channels) {
2520 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2521 wanted_spec.channels = wanted_nb_channels;
2522 if (!wanted_spec.freq) {
2523 av_log(NULL, AV_LOG_ERROR,
2524 "No more combinations to try, audio open failed\n");
2528 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2530 if (spec.format != AUDIO_S16SYS) {
2531 av_log(NULL, AV_LOG_ERROR,
2532 "SDL advised audio format %d is not supported!\n", spec.format);
2535 if (spec.channels != wanted_spec.channels) {
2536 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2537 if (!wanted_channel_layout) {
2538 av_log(NULL, AV_LOG_ERROR,
2539 "SDL advised channel count %d is not supported!\n", spec.channels);
2544 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2545 audio_hw_params->freq = spec.freq;
2546 audio_hw_params->channel_layout = wanted_channel_layout;
2547 audio_hw_params->channels = spec.channels;
2548 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2549 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);
2550 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2551 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2557 /* open a given stream. Return 0 if OK */
2558 static int stream_component_open(VideoState *is, int stream_index)
2560 AVFormatContext *ic = is->ic;
2561 AVCodecContext *avctx;
2563 const char *forced_codec_name = NULL;
2564 AVDictionary *opts = NULL;
2565 AVDictionaryEntry *t = NULL;
2566 int sample_rate, nb_channels;
2567 int64_t channel_layout;
2569 int stream_lowres = lowres;
2571 if (stream_index < 0 || stream_index >= ic->nb_streams)
2574 avctx = avcodec_alloc_context3(NULL);
2576 return AVERROR(ENOMEM);
2578 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2581 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2583 codec = avcodec_find_decoder(avctx->codec_id);
2585 switch(avctx->codec_type){
2586 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2587 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2588 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2590 if (forced_codec_name)
2591 codec = avcodec_find_decoder_by_name(forced_codec_name);
2593 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2594 "No codec could be found with name '%s'\n", forced_codec_name);
2595 else av_log(NULL, AV_LOG_WARNING,
2596 "No codec could be found with id %d\n", avctx->codec_id);
2597 ret = AVERROR(EINVAL);
2601 avctx->codec_id = codec->id;
2602 if(stream_lowres > av_codec_get_max_lowres(codec)){
2603 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2604 av_codec_get_max_lowres(codec));
2605 stream_lowres = av_codec_get_max_lowres(codec);
2607 av_codec_set_lowres(avctx, stream_lowres);
2610 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2613 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2615 if(codec->capabilities & AV_CODEC_CAP_DR1)
2616 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2619 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2620 if (!av_dict_get(opts, "threads", NULL, 0))
2621 av_dict_set(&opts, "threads", "auto", 0);
2623 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2624 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2625 av_dict_set(&opts, "refcounted_frames", "1", 0);
2626 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2629 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2630 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2631 ret = AVERROR_OPTION_NOT_FOUND;
2636 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2637 switch (avctx->codec_type) {
2638 case AVMEDIA_TYPE_AUDIO:
2643 is->audio_filter_src.freq = avctx->sample_rate;
2644 is->audio_filter_src.channels = avctx->channels;
2645 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2646 is->audio_filter_src.fmt = avctx->sample_fmt;
2647 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2649 link = is->out_audio_filter->inputs[0];
2650 sample_rate = link->sample_rate;
2651 nb_channels = avfilter_link_get_channels(link);
2652 channel_layout = link->channel_layout;
2655 sample_rate = avctx->sample_rate;
2656 nb_channels = avctx->channels;
2657 channel_layout = avctx->channel_layout;
2660 /* prepare audio output */
2661 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2663 is->audio_hw_buf_size = ret;
2664 is->audio_src = is->audio_tgt;
2665 is->audio_buf_size = 0;
2666 is->audio_buf_index = 0;
2668 /* init averaging filter */
2669 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2670 is->audio_diff_avg_count = 0;
2671 /* since we do not have a precise anough audio FIFO fullness,
2672 we correct audio sync only if larger than this threshold */
2673 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2675 is->audio_stream = stream_index;
2676 is->audio_st = ic->streams[stream_index];
2678 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2679 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2680 is->auddec.start_pts = is->audio_st->start_time;
2681 is->auddec.start_pts_tb = is->audio_st->time_base;
2683 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2687 case AVMEDIA_TYPE_VIDEO:
2688 is->video_stream = stream_index;
2689 is->video_st = ic->streams[stream_index];
2691 is->viddec_width = avctx->width;
2692 is->viddec_height = avctx->height;
2694 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2695 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2697 is->queue_attachments_req = 1;
2699 case AVMEDIA_TYPE_SUBTITLE:
2700 is->subtitle_stream = stream_index;
2701 is->subtitle_st = ic->streams[stream_index];
2703 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2704 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2713 avcodec_free_context(&avctx);
2715 av_dict_free(&opts);
2720 static int decode_interrupt_cb(void *ctx)
2722 VideoState *is = ctx;
2723 return is->abort_request;
2726 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2727 return stream_id < 0 ||
2728 queue->abort_request ||
2729 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2730 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2733 static int is_realtime(AVFormatContext *s)
2735 if( !strcmp(s->iformat->name, "rtp")
2736 || !strcmp(s->iformat->name, "rtsp")
2737 || !strcmp(s->iformat->name, "sdp")
2741 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2742 || !strncmp(s->filename, "udp:", 4)
2749 /* this thread gets the stream from the disk or the network */
2750 static int read_thread(void *arg)
2752 VideoState *is = arg;
2753 AVFormatContext *ic = NULL;
2755 int st_index[AVMEDIA_TYPE_NB];
2756 AVPacket pkt1, *pkt = &pkt1;
2757 int64_t stream_start_time;
2758 int pkt_in_play_range = 0;
2759 AVDictionaryEntry *t;
2760 AVDictionary **opts;
2761 int orig_nb_streams;
2762 SDL_mutex *wait_mutex = SDL_CreateMutex();
2763 int scan_all_pmts_set = 0;
2767 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2768 ret = AVERROR(ENOMEM);
2772 memset(st_index, -1, sizeof(st_index));
2773 is->last_video_stream = is->video_stream = -1;
2774 is->last_audio_stream = is->audio_stream = -1;
2775 is->last_subtitle_stream = is->subtitle_stream = -1;
2778 ic = avformat_alloc_context();
2780 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2781 ret = AVERROR(ENOMEM);
2784 ic->interrupt_callback.callback = decode_interrupt_cb;
2785 ic->interrupt_callback.opaque = is;
2786 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2787 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2788 scan_all_pmts_set = 1;
2790 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2792 print_error(is->filename, err);
2796 if (scan_all_pmts_set)
2797 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2799 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2800 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2801 ret = AVERROR_OPTION_NOT_FOUND;
2807 ic->flags |= AVFMT_FLAG_GENPTS;
2809 av_format_inject_global_side_data(ic);
2811 opts = setup_find_stream_info_opts(ic, codec_opts);
2812 orig_nb_streams = ic->nb_streams;
2814 err = avformat_find_stream_info(ic, opts);
2816 for (i = 0; i < orig_nb_streams; i++)
2817 av_dict_free(&opts[i]);
2821 av_log(NULL, AV_LOG_WARNING,
2822 "%s: could not find codec parameters\n", is->filename);
2828 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2830 if (seek_by_bytes < 0)
2831 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2833 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2835 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2836 window_title = av_asprintf("%s - %s", t->value, input_filename);
2838 /* if seeking requested, we execute it */
2839 if (start_time != AV_NOPTS_VALUE) {
2842 timestamp = start_time;
2843 /* add the stream start time */
2844 if (ic->start_time != AV_NOPTS_VALUE)
2845 timestamp += ic->start_time;
2846 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2848 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2849 is->filename, (double)timestamp / AV_TIME_BASE);
2853 is->realtime = is_realtime(ic);
2856 av_dump_format(ic, 0, is->filename, 0);
2858 for (i = 0; i < ic->nb_streams; i++) {
2859 AVStream *st = ic->streams[i];
2860 enum AVMediaType type = st->codecpar->codec_type;
2861 st->discard = AVDISCARD_ALL;
2862 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2863 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2866 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2867 if (wanted_stream_spec[i] && st_index[i] == -1) {
2868 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));
2869 st_index[i] = INT_MAX;
2874 st_index[AVMEDIA_TYPE_VIDEO] =
2875 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2876 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2878 st_index[AVMEDIA_TYPE_AUDIO] =
2879 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2880 st_index[AVMEDIA_TYPE_AUDIO],
2881 st_index[AVMEDIA_TYPE_VIDEO],
2883 if (!video_disable && !subtitle_disable)
2884 st_index[AVMEDIA_TYPE_SUBTITLE] =
2885 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2886 st_index[AVMEDIA_TYPE_SUBTITLE],
2887 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2888 st_index[AVMEDIA_TYPE_AUDIO] :
2889 st_index[AVMEDIA_TYPE_VIDEO]),
2892 is->show_mode = show_mode;
2893 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2894 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2895 AVCodecParameters *codecpar = st->codecpar;
2896 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2897 if (codecpar->width)
2898 set_default_window_size(codecpar->width, codecpar->height, sar);
2901 /* open the streams */
2902 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2903 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2907 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2908 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2910 if (is->show_mode == SHOW_MODE_NONE)
2911 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2913 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2914 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2917 if (is->video_stream < 0 && is->audio_stream < 0) {
2918 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2924 if (infinite_buffer < 0 && is->realtime)
2925 infinite_buffer = 1;
2928 if (is->abort_request)
2930 if (is->paused != is->last_paused) {
2931 is->last_paused = is->paused;
2933 is->read_pause_return = av_read_pause(ic);
2937 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2939 (!strcmp(ic->iformat->name, "rtsp") ||
2940 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2941 /* wait 10 ms to avoid trying to get another packet */
2948 int64_t seek_target = is->seek_pos;
2949 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2950 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2951 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2952 // of the seek_pos/seek_rel variables
2954 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2956 av_log(NULL, AV_LOG_ERROR,
2957 "%s: error while seeking\n", is->ic->filename);
2959 if (is->audio_stream >= 0) {
2960 packet_queue_flush(&is->audioq);
2961 packet_queue_put(&is->audioq, &flush_pkt);
2963 if (is->subtitle_stream >= 0) {
2964 packet_queue_flush(&is->subtitleq);
2965 packet_queue_put(&is->subtitleq, &flush_pkt);
2967 if (is->video_stream >= 0) {
2968 packet_queue_flush(&is->videoq);
2969 packet_queue_put(&is->videoq, &flush_pkt);
2971 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2972 set_clock(&is->extclk, NAN, 0);
2974 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2978 is->queue_attachments_req = 1;
2981 step_to_next_frame(is);
2983 if (is->queue_attachments_req) {
2984 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2986 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2988 packet_queue_put(&is->videoq, ©);
2989 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2991 is->queue_attachments_req = 0;
2994 /* if the queue are full, no need to read more */
2995 if (infinite_buffer<1 &&
2996 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2997 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2998 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2999 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
3001 SDL_LockMutex(wait_mutex);
3002 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3003 SDL_UnlockMutex(wait_mutex);
3007 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3008 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3009 if (loop != 1 && (!loop || --loop)) {
3010 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3011 } else if (autoexit) {
3016 ret = av_read_frame(ic, pkt);
3018 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3019 if (is->video_stream >= 0)
3020 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3021 if (is->audio_stream >= 0)
3022 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3023 if (is->subtitle_stream >= 0)
3024 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3027 if (ic->pb && ic->pb->error)
3029 SDL_LockMutex(wait_mutex);
3030 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3031 SDL_UnlockMutex(wait_mutex);
3036 /* check if packet is in play range specified by user, then queue, otherwise discard */
3037 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3038 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3039 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3040 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3041 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3042 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3043 <= ((double)duration / 1000000);
3044 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3045 packet_queue_put(&is->audioq, pkt);
3046 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3047 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3048 packet_queue_put(&is->videoq, pkt);
3049 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3050 packet_queue_put(&is->subtitleq, pkt);
3052 av_packet_unref(pkt);
3059 avformat_close_input(&ic);
3064 event.type = FF_QUIT_EVENT;
3065 event.user.data1 = is;
3066 SDL_PushEvent(&event);
3068 SDL_DestroyMutex(wait_mutex);
3072 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3076 is = av_mallocz(sizeof(VideoState));
3079 is->filename = av_strdup(filename);
3082 is->iformat = iformat;
3086 /* start video display */
3087 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3089 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3091 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3094 if (packet_queue_init(&is->videoq) < 0 ||
3095 packet_queue_init(&is->audioq) < 0 ||
3096 packet_queue_init(&is->subtitleq) < 0)
3099 if (!(is->continue_read_thread = SDL_CreateCond())) {
3100 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3104 init_clock(&is->vidclk, &is->videoq.serial);
3105 init_clock(&is->audclk, &is->audioq.serial);
3106 init_clock(&is->extclk, &is->extclk.serial);
3107 is->audio_clock_serial = -1;
3108 is->audio_volume = SDL_MIX_MAXVOLUME;
3110 is->av_sync_type = av_sync_type;
3111 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3112 if (!is->read_tid) {
3113 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3121 static void stream_cycle_channel(VideoState *is, int codec_type)
3123 AVFormatContext *ic = is->ic;
3124 int start_index, stream_index;
3127 AVProgram *p = NULL;
3128 int nb_streams = is->ic->nb_streams;
3130 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3131 start_index = is->last_video_stream;
3132 old_index = is->video_stream;
3133 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3134 start_index = is->last_audio_stream;
3135 old_index = is->audio_stream;
3137 start_index = is->last_subtitle_stream;
3138 old_index = is->subtitle_stream;
3140 stream_index = start_index;
3142 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3143 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3145 nb_streams = p->nb_stream_indexes;
3146 for (start_index = 0; start_index < nb_streams; start_index++)
3147 if (p->stream_index[start_index] == stream_index)
3149 if (start_index == nb_streams)
3151 stream_index = start_index;
3156 if (++stream_index >= nb_streams)
3158 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3161 is->last_subtitle_stream = -1;
3164 if (start_index == -1)
3168 if (stream_index == start_index)
3170 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3171 if (st->codecpar->codec_type == codec_type) {
3172 /* check that parameters are OK */
3173 switch (codec_type) {
3174 case AVMEDIA_TYPE_AUDIO:
3175 if (st->codecpar->sample_rate != 0 &&
3176 st->codecpar->channels != 0)
3179 case AVMEDIA_TYPE_VIDEO:
3180 case AVMEDIA_TYPE_SUBTITLE:
3188 if (p && stream_index != -1)
3189 stream_index = p->stream_index[stream_index];
3190 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3191 av_get_media_type_string(codec_type),
3195 stream_component_close(is, old_index);
3196 stream_component_open(is, stream_index);
3200 static void toggle_full_screen(VideoState *is)
3202 is_full_screen = !is_full_screen;
3203 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3206 static void toggle_audio_display(VideoState *is)
3208 int next = is->show_mode;
3210 next = (next + 1) % SHOW_MODE_NB;
3211 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3212 if (is->show_mode != next) {
3213 is->force_refresh = 1;
3214 is->show_mode = next;
3218 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3219 double remaining_time = 0.0;
3221 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3222 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3226 if (remaining_time > 0.0)
3227 av_usleep((int64_t)(remaining_time * 1000000.0));
3228 remaining_time = REFRESH_RATE;
3229 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3230 video_refresh(is, &remaining_time);
3235 static void seek_chapter(VideoState *is, int incr)
3237 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3240 if (!is->ic->nb_chapters)
3243 /* find the current chapter */
3244 for (i = 0; i < is->ic->nb_chapters; i++) {
3245 AVChapter *ch = is->ic->chapters[i];
3246 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3254 if (i >= is->ic->nb_chapters)
3257 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3258 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3259 AV_TIME_BASE_Q), 0, 0);
3262 /* handle an event sent by the GUI */
3263 static void event_loop(VideoState *cur_stream)
3266 double incr, pos, frac;
3270 refresh_loop_wait_event(cur_stream, &event);
3271 switch (event.type) {
3273 if (exit_on_keydown) {
3274 do_exit(cur_stream);
3277 switch (event.key.keysym.sym) {
3280 do_exit(cur_stream);
3283 toggle_full_screen(cur_stream);
3284 cur_stream->force_refresh = 1;
3288 toggle_pause(cur_stream);
3291 toggle_mute(cur_stream);
3293 case SDLK_KP_MULTIPLY:
3295 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3297 case SDLK_KP_DIVIDE:
3299 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3301 case SDLK_s: // S: Step to next frame
3302 step_to_next_frame(cur_stream);
3305 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3308 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3311 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3312 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3313 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3316 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3320 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3321 if (++cur_stream->vfilter_idx >= nb_vfilters)
3322 cur_stream->vfilter_idx = 0;
3324 cur_stream->vfilter_idx = 0;
3325 toggle_audio_display(cur_stream);
3328 toggle_audio_display(cur_stream);
3332 if (cur_stream->ic->nb_chapters <= 1) {
3336 seek_chapter(cur_stream, 1);
3339 if (cur_stream->ic->nb_chapters <= 1) {
3343 seek_chapter(cur_stream, -1);
3357 if (seek_by_bytes) {
3359 if (pos < 0 && cur_stream->video_stream >= 0)
3360 pos = frame_queue_last_pos(&cur_stream->pictq);
3361 if (pos < 0 && cur_stream->audio_stream >= 0)
3362 pos = frame_queue_last_pos(&cur_stream->sampq);
3364 pos = avio_tell(cur_stream->ic->pb);
3365 if (cur_stream->ic->bit_rate)
3366 incr *= cur_stream->ic->bit_rate / 8.0;
3370 stream_seek(cur_stream, pos, incr, 1);
3372 pos = get_master_clock(cur_stream);
3374 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3376 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3377 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3378 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3385 case SDL_MOUSEBUTTONDOWN:
3386 if (exit_on_mousedown) {
3387 do_exit(cur_stream);
3390 if (event.button.button == SDL_BUTTON_LEFT) {
3391 static int64_t last_mouse_left_click = 0;
3392 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3393 toggle_full_screen(cur_stream);
3394 cur_stream->force_refresh = 1;
3395 last_mouse_left_click = 0;
3397 last_mouse_left_click = av_gettime_relative();
3400 case SDL_MOUSEMOTION:
3401 if (cursor_hidden) {
3405 cursor_last_shown = av_gettime_relative();
3406 if (event.type == SDL_MOUSEBUTTONDOWN) {
3407 if (event.button.button != SDL_BUTTON_RIGHT)
3411 if (!(event.motion.state & SDL_BUTTON_RMASK))
3415 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3416 uint64_t size = avio_size(cur_stream->ic->pb);
3417 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3421 int tns, thh, tmm, tss;
3422 tns = cur_stream->ic->duration / 1000000LL;
3424 tmm = (tns % 3600) / 60;
3426 frac = x / cur_stream->width;
3429 mm = (ns % 3600) / 60;
3431 av_log(NULL, AV_LOG_INFO,
3432 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3433 hh, mm, ss, thh, tmm, tss);
3434 ts = frac * cur_stream->ic->duration;
3435 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3436 ts += cur_stream->ic->start_time;
3437 stream_seek(cur_stream, ts, 0, 0);
3440 case SDL_WINDOWEVENT:
3441 switch (event.window.event) {
3442 case SDL_WINDOWEVENT_RESIZED:
3443 screen_width = cur_stream->width = event.window.data1;
3444 screen_height = cur_stream->height = event.window.data2;
3445 if (cur_stream->vis_texture) {
3446 SDL_DestroyTexture(cur_stream->vis_texture);
3447 cur_stream->vis_texture = NULL;
3449 case SDL_WINDOWEVENT_EXPOSED:
3450 cur_stream->force_refresh = 1;
3455 do_exit(cur_stream);
3457 case FF_ALLOC_EVENT:
3458 alloc_picture(event.user.data1);
3466 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3468 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3469 return opt_default(NULL, "video_size", arg);
3472 static int opt_width(void *optctx, const char *opt, const char *arg)
3474 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3478 static int opt_height(void *optctx, const char *opt, const char *arg)
3480 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3484 static int opt_format(void *optctx, const char *opt, const char *arg)
3486 file_iformat = av_find_input_format(arg);
3487 if (!file_iformat) {
3488 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3489 return AVERROR(EINVAL);
3494 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3496 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3497 return opt_default(NULL, "pixel_format", arg);
3500 static int opt_sync(void *optctx, const char *opt, const char *arg)
3502 if (!strcmp(arg, "audio"))
3503 av_sync_type = AV_SYNC_AUDIO_MASTER;
3504 else if (!strcmp(arg, "video"))
3505 av_sync_type = AV_SYNC_VIDEO_MASTER;
3506 else if (!strcmp(arg, "ext"))
3507 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3509 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3515 static int opt_seek(void *optctx, const char *opt, const char *arg)
3517 start_time = parse_time_or_die(opt, arg, 1);
3521 static int opt_duration(void *optctx, const char *opt, const char *arg)
3523 duration = parse_time_or_die(opt, arg, 1);
3527 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3529 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3530 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3531 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3532 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3536 static void opt_input_file(void *optctx, const char *filename)
3538 if (input_filename) {
3539 av_log(NULL, AV_LOG_FATAL,
3540 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3541 filename, input_filename);
3544 if (!strcmp(filename, "-"))
3546 input_filename = filename;
3549 static int opt_codec(void *optctx, const char *opt, const char *arg)
3551 const char *spec = strchr(opt, ':');
3553 av_log(NULL, AV_LOG_ERROR,
3554 "No media specifier was specified in '%s' in option '%s'\n",
3556 return AVERROR(EINVAL);
3560 case 'a' : audio_codec_name = arg; break;
3561 case 's' : subtitle_codec_name = arg; break;
3562 case 'v' : video_codec_name = arg; break;
3564 av_log(NULL, AV_LOG_ERROR,
3565 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3566 return AVERROR(EINVAL);
3573 static const OptionDef options[] = {
3574 #include "cmdutils_common_opts.h"
3575 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3576 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3577 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3578 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3579 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3580 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3581 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3582 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3583 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3584 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3585 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3586 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3587 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3588 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3589 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3590 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3591 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3592 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3593 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3594 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3595 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3596 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3597 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3598 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3599 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3600 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3601 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3602 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3603 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3605 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3606 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3608 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3609 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3610 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3611 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3612 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3613 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3614 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3615 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3616 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3620 static void show_usage(void)
3622 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3623 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3624 av_log(NULL, AV_LOG_INFO, "\n");
3627 void show_help_default(const char *opt, const char *arg)
3629 av_log_set_callback(log_callback_help);
3631 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3632 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3634 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3635 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3636 #if !CONFIG_AVFILTER
3637 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3639 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3641 printf("\nWhile playing:\n"
3643 "f toggle full screen\n"
3646 "9, 0 decrease and increase volume respectively\n"
3647 "/, * decrease and increase volume respectively\n"
3648 "a cycle audio channel in the current program\n"
3649 "v cycle video channel\n"
3650 "t cycle subtitle channel in the current program\n"
3652 "w cycle video filters or show modes\n"
3653 "s activate frame-step mode\n"
3654 "left/right seek backward/forward 10 seconds\n"
3655 "down/up seek backward/forward 1 minute\n"
3656 "page down/page up seek backward/forward 10 minutes\n"
3657 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3658 "left double-click toggle full screen\n"
3662 static int lockmgr(void **mtx, enum AVLockOp op)
3665 case AV_LOCK_CREATE:
3666 *mtx = SDL_CreateMutex();
3668 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3672 case AV_LOCK_OBTAIN:
3673 return !!SDL_LockMutex(*mtx);
3674 case AV_LOCK_RELEASE:
3675 return !!SDL_UnlockMutex(*mtx);
3676 case AV_LOCK_DESTROY:
3677 SDL_DestroyMutex(*mtx);
3683 /* Called from the main */
3684 int main(int argc, char **argv)
3691 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3692 parse_loglevel(argc, argv, options);
3694 /* register all codecs, demux and protocols */
3696 avdevice_register_all();
3699 avfilter_register_all();
3702 avformat_network_init();
3706 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3707 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3709 show_banner(argc, argv, options);
3711 parse_options(NULL, argc, argv, options, opt_input_file);
3713 if (!input_filename) {
3715 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3716 av_log(NULL, AV_LOG_FATAL,
3717 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3721 if (display_disable) {
3724 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3726 flags &= ~SDL_INIT_AUDIO;
3728 /* Try to work around an occasional ALSA buffer underflow issue when the
3729 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3730 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3731 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3733 if (display_disable)
3734 flags &= ~SDL_INIT_VIDEO;
3735 if (SDL_Init (flags)) {
3736 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3737 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3741 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3742 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3744 if (av_lockmgr_register(lockmgr)) {
3745 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3749 av_init_packet(&flush_pkt);
3750 flush_pkt.data = (uint8_t *)&flush_pkt;
3752 is = stream_open(input_filename, file_iformat);
3754 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");