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/avcodec.h"
52 # include "libavfilter/avfilter.h"
53 # include "libavfilter/buffersink.h"
54 # include "libavfilter/buffersrc.h"
58 #include <SDL_thread.h>
64 const char program_name[] = "ffplay";
65 const int program_birth_year = 2003;
67 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
69 #define EXTERNAL_CLOCK_MIN_FRAMES 2
70 #define EXTERNAL_CLOCK_MAX_FRAMES 10
72 /* Minimum SDL audio buffer size, in samples. */
73 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
74 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
75 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
77 /* no AV sync correction is done if below the minimum AV sync threshold */
78 #define AV_SYNC_THRESHOLD_MIN 0.04
79 /* AV sync correction is done if above the maximum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MAX 0.1
81 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
82 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
83 /* no AV correction is done if too big error */
84 #define AV_NOSYNC_THRESHOLD 10.0
86 /* maximum audio speed change to get correct sync */
87 #define SAMPLE_CORRECTION_PERCENT_MAX 10
89 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
90 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
91 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
92 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
94 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
95 #define AUDIO_DIFF_AVG_NB 20
97 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
98 #define REFRESH_RATE 0.01
100 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
101 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
102 #define SAMPLE_ARRAY_SIZE (8 * 65536)
104 #define CURSOR_HIDE_DELAY 1000000
106 static unsigned sws_flags = SWS_BICUBIC;
108 typedef struct MyAVPacketList {
110 struct MyAVPacketList *next;
114 typedef struct PacketQueue {
115 MyAVPacketList *first_pkt, *last_pkt;
124 #define VIDEO_PICTURE_QUEUE_SIZE 3
125 #define SUBPICTURE_QUEUE_SIZE 16
126 #define SAMPLE_QUEUE_SIZE 9
127 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
129 typedef struct AudioParams {
132 int64_t channel_layout;
133 enum AVSampleFormat fmt;
138 typedef struct Clock {
139 double pts; /* clock base */
140 double pts_drift; /* clock base minus time at which we updated the clock */
143 int serial; /* clock is based on a packet with this serial */
145 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
148 /* Common struct for handling all types of decoded data and allocated render buffers. */
149 typedef struct Frame {
153 double pts; /* presentation timestamp for the frame */
154 double duration; /* estimated duration of the frame */
155 int64_t pos; /* byte position of the frame in the input file */
164 typedef struct FrameQueue {
165 Frame queue[FRAME_QUEUE_SIZE];
178 AV_SYNC_AUDIO_MASTER, /* default choice */
179 AV_SYNC_VIDEO_MASTER,
180 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
183 typedef struct Decoder {
187 AVCodecContext *avctx;
191 SDL_cond *empty_queue_cond;
193 AVRational start_pts_tb;
195 AVRational next_pts_tb;
196 SDL_Thread *decoder_tid;
199 typedef struct VideoState {
200 SDL_Thread *read_tid;
201 AVInputFormat *iformat;
206 int queue_attachments_req;
211 int read_pause_return;
235 int audio_clock_serial;
236 double audio_diff_cum; /* used for AV difference average computation */
237 double audio_diff_avg_coef;
238 double audio_diff_threshold;
239 int audio_diff_avg_count;
242 int audio_hw_buf_size;
243 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
246 unsigned int audio_buf_size; /* in bytes */
247 unsigned int audio_buf1_size;
248 int audio_buf_index; /* in bytes */
249 int audio_write_buf_size;
250 struct AudioParams audio_src;
252 struct AudioParams audio_filter_src;
254 struct AudioParams audio_tgt;
255 struct SwrContext *swr_ctx;
256 int frame_drops_early;
257 int frame_drops_late;
260 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
262 int16_t sample_array[SAMPLE_ARRAY_SIZE];
263 int sample_array_index;
267 FFTSample *rdft_data;
269 double last_vis_time;
272 AVStream *subtitle_st;
273 PacketQueue subtitleq;
276 double frame_last_returned_time;
277 double frame_last_filter_delay;
281 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
283 struct SwsContext *img_convert_ctx;
285 struct SwsContext *sub_convert_ctx;
286 SDL_Rect last_display_rect;
290 int width, height, xleft, ytop;
295 AVFilterContext *in_video_filter; // the first filter in the video chain
296 AVFilterContext *out_video_filter; // the last filter in the video chain
297 AVFilterContext *in_audio_filter; // the first filter in the audio chain
298 AVFilterContext *out_audio_filter; // the last filter in the audio chain
299 AVFilterGraph *agraph; // audio filter graph
302 int last_video_stream, last_audio_stream, last_subtitle_stream;
304 SDL_cond *continue_read_thread;
307 /* options specified by the user */
308 static AVInputFormat *file_iformat;
309 static const char *input_filename;
310 static const char *window_title;
311 static int fs_screen_width;
312 static int fs_screen_height;
313 static int default_width = 640;
314 static int default_height = 480;
315 static int screen_width = 0;
316 static int screen_height = 0;
317 static int audio_disable;
318 static int video_disable;
319 static int subtitle_disable;
320 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
321 static int seek_by_bytes = -1;
322 static int display_disable;
323 static int show_status = 1;
324 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
325 static int64_t start_time = AV_NOPTS_VALUE;
326 static int64_t duration = AV_NOPTS_VALUE;
328 static int genpts = 0;
329 static int lowres = 0;
330 static int decoder_reorder_pts = -1;
332 static int exit_on_keydown;
333 static int exit_on_mousedown;
335 static int framedrop = -1;
336 static int infinite_buffer = -1;
337 static enum ShowMode show_mode = SHOW_MODE_NONE;
338 static const char *audio_codec_name;
339 static const char *subtitle_codec_name;
340 static const char *video_codec_name;
341 double rdftspeed = 0.02;
342 static int64_t cursor_last_shown;
343 static int cursor_hidden = 0;
345 static const char **vfilters_list = NULL;
346 static int nb_vfilters = 0;
347 static char *afilters = NULL;
349 static int autorotate = 1;
351 /* current context */
352 static int is_full_screen;
353 static int64_t audio_callback_time;
355 static AVPacket flush_pkt;
357 #define FF_ALLOC_EVENT (SDL_USEREVENT)
358 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
360 static SDL_Surface *screen;
363 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
365 GROW_ARRAY(vfilters_list, nb_vfilters);
366 vfilters_list[nb_vfilters - 1] = arg;
372 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
373 enum AVSampleFormat fmt2, int64_t channel_count2)
375 /* If channel count == 1, planar and non-planar formats are the same */
376 if (channel_count1 == 1 && channel_count2 == 1)
377 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
379 return channel_count1 != channel_count2 || fmt1 != fmt2;
383 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
385 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
386 return channel_layout;
391 static void free_picture(Frame *vp);
393 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
395 MyAVPacketList *pkt1;
397 if (q->abort_request)
400 pkt1 = av_malloc(sizeof(MyAVPacketList));
405 if (pkt == &flush_pkt)
407 pkt1->serial = q->serial;
412 q->last_pkt->next = pkt1;
415 q->size += pkt1->pkt.size + sizeof(*pkt1);
416 /* XXX: should duplicate packet data in DV case */
417 SDL_CondSignal(q->cond);
421 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
425 /* duplicate the packet */
426 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
429 SDL_LockMutex(q->mutex);
430 ret = packet_queue_put_private(q, pkt);
431 SDL_UnlockMutex(q->mutex);
433 if (pkt != &flush_pkt && ret < 0)
439 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
441 AVPacket pkt1, *pkt = &pkt1;
445 pkt->stream_index = stream_index;
446 return packet_queue_put(q, pkt);
449 /* packet queue handling */
450 static void packet_queue_init(PacketQueue *q)
452 memset(q, 0, sizeof(PacketQueue));
453 q->mutex = SDL_CreateMutex();
454 q->cond = SDL_CreateCond();
455 q->abort_request = 1;
458 static void packet_queue_flush(PacketQueue *q)
460 MyAVPacketList *pkt, *pkt1;
462 SDL_LockMutex(q->mutex);
463 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
465 av_free_packet(&pkt->pkt);
472 SDL_UnlockMutex(q->mutex);
475 static void packet_queue_destroy(PacketQueue *q)
477 packet_queue_flush(q);
478 SDL_DestroyMutex(q->mutex);
479 SDL_DestroyCond(q->cond);
482 static void packet_queue_abort(PacketQueue *q)
484 SDL_LockMutex(q->mutex);
486 q->abort_request = 1;
488 SDL_CondSignal(q->cond);
490 SDL_UnlockMutex(q->mutex);
493 static void packet_queue_start(PacketQueue *q)
495 SDL_LockMutex(q->mutex);
496 q->abort_request = 0;
497 packet_queue_put_private(q, &flush_pkt);
498 SDL_UnlockMutex(q->mutex);
501 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
502 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
504 MyAVPacketList *pkt1;
507 SDL_LockMutex(q->mutex);
510 if (q->abort_request) {
517 q->first_pkt = pkt1->next;
521 q->size -= pkt1->pkt.size + sizeof(*pkt1);
524 *serial = pkt1->serial;
532 SDL_CondWait(q->cond, q->mutex);
535 SDL_UnlockMutex(q->mutex);
539 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
540 memset(d, 0, sizeof(Decoder));
543 d->empty_queue_cond = empty_queue_cond;
544 d->start_pts = AV_NOPTS_VALUE;
547 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
553 if (d->queue->abort_request)
556 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
559 if (d->queue->nb_packets == 0)
560 SDL_CondSignal(d->empty_queue_cond);
561 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
563 if (pkt.data == flush_pkt.data) {
564 avcodec_flush_buffers(d->avctx);
566 d->next_pts = d->start_pts;
567 d->next_pts_tb = d->start_pts_tb;
569 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
570 av_free_packet(&d->pkt);
571 d->pkt_temp = d->pkt = pkt;
572 d->packet_pending = 1;
575 switch (d->avctx->codec_type) {
576 case AVMEDIA_TYPE_VIDEO:
577 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
579 if (decoder_reorder_pts == -1) {
580 frame->pts = av_frame_get_best_effort_timestamp(frame);
581 } else if (decoder_reorder_pts) {
582 frame->pts = frame->pkt_pts;
584 frame->pts = frame->pkt_dts;
588 case AVMEDIA_TYPE_AUDIO:
589 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
591 AVRational tb = (AVRational){1, frame->sample_rate};
592 if (frame->pts != AV_NOPTS_VALUE)
593 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
594 else if (frame->pkt_pts != AV_NOPTS_VALUE)
595 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
596 else if (d->next_pts != AV_NOPTS_VALUE)
597 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
598 if (frame->pts != AV_NOPTS_VALUE) {
599 d->next_pts = frame->pts + frame->nb_samples;
604 case AVMEDIA_TYPE_SUBTITLE:
605 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
610 d->packet_pending = 0;
613 d->pkt_temp.pts = AV_NOPTS_VALUE;
614 if (d->pkt_temp.data) {
615 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
616 ret = d->pkt_temp.size;
617 d->pkt_temp.data += ret;
618 d->pkt_temp.size -= ret;
619 if (d->pkt_temp.size <= 0)
620 d->packet_pending = 0;
623 d->packet_pending = 0;
624 d->finished = d->pkt_serial;
628 } while (!got_frame && !d->finished);
633 static void decoder_destroy(Decoder *d) {
634 av_free_packet(&d->pkt);
637 static void frame_queue_unref_item(Frame *vp)
639 av_frame_unref(vp->frame);
640 avsubtitle_free(&vp->sub);
643 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
646 memset(f, 0, sizeof(FrameQueue));
647 if (!(f->mutex = SDL_CreateMutex()))
648 return AVERROR(ENOMEM);
649 if (!(f->cond = SDL_CreateCond()))
650 return AVERROR(ENOMEM);
652 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
653 f->keep_last = !!keep_last;
654 for (i = 0; i < f->max_size; i++)
655 if (!(f->queue[i].frame = av_frame_alloc()))
656 return AVERROR(ENOMEM);
660 static void frame_queue_destory(FrameQueue *f)
663 for (i = 0; i < f->max_size; i++) {
664 Frame *vp = &f->queue[i];
665 frame_queue_unref_item(vp);
666 av_frame_free(&vp->frame);
669 SDL_DestroyMutex(f->mutex);
670 SDL_DestroyCond(f->cond);
673 static void frame_queue_signal(FrameQueue *f)
675 SDL_LockMutex(f->mutex);
676 SDL_CondSignal(f->cond);
677 SDL_UnlockMutex(f->mutex);
680 static Frame *frame_queue_peek(FrameQueue *f)
682 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
685 static Frame *frame_queue_peek_next(FrameQueue *f)
687 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
690 static Frame *frame_queue_peek_last(FrameQueue *f)
692 return &f->queue[f->rindex];
695 static Frame *frame_queue_peek_writable(FrameQueue *f)
697 /* wait until we have space to put a new frame */
698 SDL_LockMutex(f->mutex);
699 while (f->size >= f->max_size &&
700 !f->pktq->abort_request) {
701 SDL_CondWait(f->cond, f->mutex);
703 SDL_UnlockMutex(f->mutex);
705 if (f->pktq->abort_request)
708 return &f->queue[f->windex];
711 static Frame *frame_queue_peek_readable(FrameQueue *f)
713 /* wait until we have a readable a new frame */
714 SDL_LockMutex(f->mutex);
715 while (f->size - f->rindex_shown <= 0 &&
716 !f->pktq->abort_request) {
717 SDL_CondWait(f->cond, f->mutex);
719 SDL_UnlockMutex(f->mutex);
721 if (f->pktq->abort_request)
724 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
727 static void frame_queue_push(FrameQueue *f)
729 if (++f->windex == f->max_size)
731 SDL_LockMutex(f->mutex);
733 SDL_CondSignal(f->cond);
734 SDL_UnlockMutex(f->mutex);
737 static void frame_queue_next(FrameQueue *f)
739 if (f->keep_last && !f->rindex_shown) {
743 frame_queue_unref_item(&f->queue[f->rindex]);
744 if (++f->rindex == f->max_size)
746 SDL_LockMutex(f->mutex);
748 SDL_CondSignal(f->cond);
749 SDL_UnlockMutex(f->mutex);
752 /* jump back to the previous frame if available by resetting rindex_shown */
753 static int frame_queue_prev(FrameQueue *f)
755 int ret = f->rindex_shown;
760 /* return the number of undisplayed frames in the queue */
761 static int frame_queue_nb_remaining(FrameQueue *f)
763 return f->size - f->rindex_shown;
766 /* return last shown position */
767 static int64_t frame_queue_last_pos(FrameQueue *f)
769 Frame *fp = &f->queue[f->rindex];
770 if (f->rindex_shown && fp->serial == f->pktq->serial)
776 static void decoder_abort(Decoder *d, FrameQueue *fq)
778 packet_queue_abort(d->queue);
779 frame_queue_signal(fq);
780 SDL_WaitThread(d->decoder_tid, NULL);
781 d->decoder_tid = NULL;
782 packet_queue_flush(d->queue);
785 static inline void fill_rectangle(SDL_Surface *screen,
786 int x, int y, int w, int h, int color, int update)
793 SDL_FillRect(screen, &rect, color);
794 if (update && w > 0 && h > 0)
795 SDL_UpdateRect(screen, x, y, w, h);
798 /* draw only the border of a rectangle */
799 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
803 /* fill the background */
807 w2 = width - (x + w);
813 h2 = height - (y + h);
816 fill_rectangle(screen,
820 fill_rectangle(screen,
821 xleft + width - w2, ytop,
824 fill_rectangle(screen,
828 fill_rectangle(screen,
829 xleft + w1, ytop + height - h2,
834 #define ALPHA_BLEND(a, oldp, newp, s)\
835 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
841 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
843 int x, y, Y, U, V, A;
844 uint8_t *lum, *cb, *cr;
845 int dstx, dsty, dstw, dsth;
846 const AVPicture *src = &rect->pict;
848 dstw = av_clip(rect->w, 0, imgw);
849 dsth = av_clip(rect->h, 0, imgh);
850 dstx = av_clip(rect->x, 0, imgw - dstw);
851 dsty = av_clip(rect->y, 0, imgh - dsth);
852 lum = dst->data[0] + dstx + dsty * dst->linesize[0];
853 cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
854 cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
856 for (y = 0; y<dsth; y++) {
857 for (x = 0; x<dstw; x++) {
858 Y = src->data[0][x + y*src->linesize[0]];
859 A = src->data[3][x + y*src->linesize[3]];
860 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
863 lum += dst->linesize[0] - dstw;
866 for (y = 0; y<dsth/2; y++) {
867 for (x = 0; x<dstw/2; x++) {
868 U = src->data[1][x + y*src->linesize[1]];
869 V = src->data[2][x + y*src->linesize[2]];
870 A = src->data[3][2*x + 2*y *src->linesize[3]]
871 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
872 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
873 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
874 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
875 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
879 cb += dst->linesize[1] - dstw/2;
880 cr += dst->linesize[2] - dstw/2;
884 static void free_picture(Frame *vp)
887 SDL_FreeYUVOverlay(vp->bmp);
892 static void calculate_display_rect(SDL_Rect *rect,
893 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
894 int pic_width, int pic_height, AVRational pic_sar)
897 int width, height, x, y;
899 if (pic_sar.num == 0)
902 aspect_ratio = av_q2d(pic_sar);
904 if (aspect_ratio <= 0.0)
906 aspect_ratio *= (float)pic_width / (float)pic_height;
908 /* XXX: we suppose the screen has a 1.0 pixel ratio */
910 width = ((int)rint(height * aspect_ratio)) & ~1;
911 if (width > scr_width) {
913 height = ((int)rint(width / aspect_ratio)) & ~1;
915 x = (scr_width - width) / 2;
916 y = (scr_height - height) / 2;
917 rect->x = scr_xleft + x;
918 rect->y = scr_ytop + y;
919 rect->w = FFMAX(width, 1);
920 rect->h = FFMAX(height, 1);
923 static void video_image_display(VideoState *is)
931 vp = frame_queue_peek(&is->pictq);
933 if (is->subtitle_st) {
934 if (frame_queue_nb_remaining(&is->subpq) > 0) {
935 sp = frame_queue_peek(&is->subpq);
937 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
938 SDL_LockYUVOverlay (vp->bmp);
940 pict.data[0] = vp->bmp->pixels[0];
941 pict.data[1] = vp->bmp->pixels[2];
942 pict.data[2] = vp->bmp->pixels[1];
944 pict.linesize[0] = vp->bmp->pitches[0];
945 pict.linesize[1] = vp->bmp->pitches[2];
946 pict.linesize[2] = vp->bmp->pitches[1];
948 for (i = 0; i < sp->sub.num_rects; i++)
949 blend_subrect(&pict, sp->sub.rects[i],
950 vp->bmp->w, vp->bmp->h);
952 SDL_UnlockYUVOverlay (vp->bmp);
957 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
959 SDL_DisplayYUVOverlay(vp->bmp, &rect);
961 if (rect.x != is->last_display_rect.x || rect.y != is->last_display_rect.y || rect.w != is->last_display_rect.w || rect.h != is->last_display_rect.h || is->force_refresh) {
962 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
963 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
964 is->last_display_rect = rect;
969 static inline int compute_mod(int a, int b)
971 return a < 0 ? a%b + b : a%b;
974 static void video_audio_display(VideoState *s)
976 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
977 int ch, channels, h, h2, bgcolor, fgcolor;
979 int rdft_bits, nb_freq;
981 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
983 nb_freq = 1 << (rdft_bits - 1);
985 /* compute display index : center on currently output samples */
986 channels = s->audio_tgt.channels;
987 nb_display_channels = channels;
989 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
991 delay = s->audio_write_buf_size;
994 /* to be more precise, we take into account the time spent since
995 the last buffer computation */
996 if (audio_callback_time) {
997 time_diff = av_gettime_relative() - audio_callback_time;
998 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1001 delay += 2 * data_used;
1002 if (delay < data_used)
1005 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1006 if (s->show_mode == SHOW_MODE_WAVES) {
1008 for (i = 0; i < 1000; i += channels) {
1009 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1010 int a = s->sample_array[idx];
1011 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1012 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1013 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1015 if (h < score && (b ^ c) < 0) {
1022 s->last_i_start = i_start;
1024 i_start = s->last_i_start;
1027 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1028 if (s->show_mode == SHOW_MODE_WAVES) {
1029 fill_rectangle(screen,
1030 s->xleft, s->ytop, s->width, s->height,
1033 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1035 /* total height for one channel */
1036 h = s->height / nb_display_channels;
1037 /* graph height / 2 */
1039 for (ch = 0; ch < nb_display_channels; ch++) {
1041 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1042 for (x = 0; x < s->width; x++) {
1043 y = (s->sample_array[i] * h2) >> 15;
1050 fill_rectangle(screen,
1051 s->xleft + x, ys, 1, y,
1054 if (i >= SAMPLE_ARRAY_SIZE)
1055 i -= SAMPLE_ARRAY_SIZE;
1059 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1061 for (ch = 1; ch < nb_display_channels; ch++) {
1062 y = s->ytop + ch * h;
1063 fill_rectangle(screen,
1064 s->xleft, y, s->width, 1,
1067 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1069 nb_display_channels= FFMIN(nb_display_channels, 2);
1070 if (rdft_bits != s->rdft_bits) {
1071 av_rdft_end(s->rdft);
1072 av_free(s->rdft_data);
1073 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1074 s->rdft_bits = rdft_bits;
1075 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1077 if (!s->rdft || !s->rdft_data){
1078 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1079 s->show_mode = SHOW_MODE_WAVES;
1082 for (ch = 0; ch < nb_display_channels; ch++) {
1083 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1085 for (x = 0; x < 2 * nb_freq; x++) {
1086 double w = (x-nb_freq) * (1.0 / nb_freq);
1087 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1089 if (i >= SAMPLE_ARRAY_SIZE)
1090 i -= SAMPLE_ARRAY_SIZE;
1092 av_rdft_calc(s->rdft, data[ch]);
1094 /* Least efficient way to do this, we should of course
1095 * directly access it but it is more than fast enough. */
1096 for (y = 0; y < s->height; y++) {
1097 double w = 1 / sqrt(nb_freq);
1098 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]));
1099 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1100 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1103 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1105 fill_rectangle(screen,
1106 s->xpos, s->height-y, 1, 1,
1110 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1113 if (s->xpos >= s->width)
1118 static void stream_close(VideoState *is)
1120 /* XXX: use a special url_shutdown call to abort parse cleanly */
1121 is->abort_request = 1;
1122 SDL_WaitThread(is->read_tid, NULL);
1123 packet_queue_destroy(&is->videoq);
1124 packet_queue_destroy(&is->audioq);
1125 packet_queue_destroy(&is->subtitleq);
1127 /* free all pictures */
1128 frame_queue_destory(&is->pictq);
1129 frame_queue_destory(&is->sampq);
1130 frame_queue_destory(&is->subpq);
1131 SDL_DestroyCond(is->continue_read_thread);
1132 #if !CONFIG_AVFILTER
1133 sws_freeContext(is->img_convert_ctx);
1135 sws_freeContext(is->sub_convert_ctx);
1139 static void do_exit(VideoState *is)
1144 av_lockmgr_register(NULL);
1147 av_freep(&vfilters_list);
1149 avformat_network_deinit();
1153 av_log(NULL, AV_LOG_QUIET, "%s", "");
1157 static void sigterm_handler(int sig)
1162 static void set_default_window_size(int width, int height, AVRational sar)
1165 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1166 default_width = rect.w;
1167 default_height = rect.h;
1170 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1172 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1175 if (is_full_screen) flags |= SDL_FULLSCREEN;
1176 else flags |= SDL_RESIZABLE;
1178 if (vp && vp->width)
1179 set_default_window_size(vp->width, vp->height, vp->sar);
1181 if (is_full_screen && fs_screen_width) {
1182 w = fs_screen_width;
1183 h = fs_screen_height;
1184 } else if (!is_full_screen && screen_width) {
1191 w = FFMIN(16383, w);
1192 if (screen && is->width == screen->w && screen->w == w
1193 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1195 screen = SDL_SetVideoMode(w, h, 0, flags);
1197 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1201 window_title = input_filename;
1202 SDL_WM_SetCaption(window_title, window_title);
1204 is->width = screen->w;
1205 is->height = screen->h;
1210 /* display the current picture, if any */
1211 static void video_display(VideoState *is)
1214 video_open(is, 0, NULL);
1215 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1216 video_audio_display(is);
1217 else if (is->video_st)
1218 video_image_display(is);
1221 static double get_clock(Clock *c)
1223 if (*c->queue_serial != c->serial)
1228 double time = av_gettime_relative() / 1000000.0;
1229 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1233 static void set_clock_at(Clock *c, double pts, int serial, double time)
1236 c->last_updated = time;
1237 c->pts_drift = c->pts - time;
1241 static void set_clock(Clock *c, double pts, int serial)
1243 double time = av_gettime_relative() / 1000000.0;
1244 set_clock_at(c, pts, serial, time);
1247 static void set_clock_speed(Clock *c, double speed)
1249 set_clock(c, get_clock(c), c->serial);
1253 static void init_clock(Clock *c, int *queue_serial)
1257 c->queue_serial = queue_serial;
1258 set_clock(c, NAN, -1);
1261 static void sync_clock_to_slave(Clock *c, Clock *slave)
1263 double clock = get_clock(c);
1264 double slave_clock = get_clock(slave);
1265 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1266 set_clock(c, slave_clock, slave->serial);
1269 static int get_master_sync_type(VideoState *is) {
1270 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1272 return AV_SYNC_VIDEO_MASTER;
1274 return AV_SYNC_AUDIO_MASTER;
1275 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1277 return AV_SYNC_AUDIO_MASTER;
1279 return AV_SYNC_EXTERNAL_CLOCK;
1281 return AV_SYNC_EXTERNAL_CLOCK;
1285 /* get the current master clock value */
1286 static double get_master_clock(VideoState *is)
1290 switch (get_master_sync_type(is)) {
1291 case AV_SYNC_VIDEO_MASTER:
1292 val = get_clock(&is->vidclk);
1294 case AV_SYNC_AUDIO_MASTER:
1295 val = get_clock(&is->audclk);
1298 val = get_clock(&is->extclk);
1304 static void check_external_clock_speed(VideoState *is) {
1305 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1306 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1307 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1308 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1309 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1310 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1312 double speed = is->extclk.speed;
1314 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1318 /* seek in the stream */
1319 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1321 if (!is->seek_req) {
1324 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1326 is->seek_flags |= AVSEEK_FLAG_BYTE;
1328 SDL_CondSignal(is->continue_read_thread);
1332 /* pause or resume the video */
1333 static void stream_toggle_pause(VideoState *is)
1336 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1337 if (is->read_pause_return != AVERROR(ENOSYS)) {
1338 is->vidclk.paused = 0;
1340 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1342 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1343 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1346 static void toggle_pause(VideoState *is)
1348 stream_toggle_pause(is);
1352 static void step_to_next_frame(VideoState *is)
1354 /* if the stream is paused unpause it, then step */
1356 stream_toggle_pause(is);
1360 static double compute_target_delay(double delay, VideoState *is)
1362 double sync_threshold, diff = 0;
1364 /* update delay to follow master synchronisation source */
1365 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1366 /* if video is slave, we try to correct big delays by
1367 duplicating or deleting a frame */
1368 diff = get_clock(&is->vidclk) - get_master_clock(is);
1370 /* skip or repeat frame. We take into account the
1371 delay to compute the threshold. I still don't know
1372 if it is the best guess */
1373 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1374 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1375 if (diff <= -sync_threshold)
1376 delay = FFMAX(0, delay + diff);
1377 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1378 delay = delay + diff;
1379 else if (diff >= sync_threshold)
1384 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1390 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1391 if (vp->serial == nextvp->serial) {
1392 double duration = nextvp->pts - vp->pts;
1393 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1394 return vp->duration;
1402 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1403 /* update current video pts */
1404 set_clock(&is->vidclk, pts, serial);
1405 sync_clock_to_slave(&is->extclk, &is->vidclk);
1408 /* called to display each frame */
1409 static void video_refresh(void *opaque, double *remaining_time)
1411 VideoState *is = opaque;
1416 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1417 check_external_clock_speed(is);
1419 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1420 time = av_gettime_relative() / 1000000.0;
1421 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1423 is->last_vis_time = time;
1425 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1430 if (is->force_refresh)
1431 redisplay = frame_queue_prev(&is->pictq);
1433 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1434 // nothing to do, no picture to display in the queue
1436 double last_duration, duration, delay;
1439 /* dequeue the picture */
1440 lastvp = frame_queue_peek_last(&is->pictq);
1441 vp = frame_queue_peek(&is->pictq);
1443 if (vp->serial != is->videoq.serial) {
1444 frame_queue_next(&is->pictq);
1449 if (lastvp->serial != vp->serial && !redisplay)
1450 is->frame_timer = av_gettime_relative() / 1000000.0;
1455 /* compute nominal last_duration */
1456 last_duration = vp_duration(is, lastvp, vp);
1460 delay = compute_target_delay(last_duration, is);
1462 time= av_gettime_relative()/1000000.0;
1463 if (time < is->frame_timer + delay && !redisplay) {
1464 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1468 is->frame_timer += delay;
1469 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1470 is->frame_timer = time;
1472 SDL_LockMutex(is->pictq.mutex);
1473 if (!redisplay && !isnan(vp->pts))
1474 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1475 SDL_UnlockMutex(is->pictq.mutex);
1477 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1478 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1479 duration = vp_duration(is, vp, nextvp);
1480 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1482 is->frame_drops_late++;
1483 frame_queue_next(&is->pictq);
1489 if (is->subtitle_st) {
1490 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1491 sp = frame_queue_peek(&is->subpq);
1493 if (frame_queue_nb_remaining(&is->subpq) > 1)
1494 sp2 = frame_queue_peek_next(&is->subpq);
1498 if (sp->serial != is->subtitleq.serial
1499 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1500 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1502 frame_queue_next(&is->subpq);
1510 /* display picture */
1511 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1514 frame_queue_next(&is->pictq);
1516 if (is->step && !is->paused)
1517 stream_toggle_pause(is);
1520 is->force_refresh = 0;
1522 static int64_t last_time;
1524 int aqsize, vqsize, sqsize;
1527 cur_time = av_gettime_relative();
1528 if (!last_time || (cur_time - last_time) >= 30000) {
1533 aqsize = is->audioq.size;
1535 vqsize = is->videoq.size;
1536 if (is->subtitle_st)
1537 sqsize = is->subtitleq.size;
1539 if (is->audio_st && is->video_st)
1540 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1541 else if (is->video_st)
1542 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1543 else if (is->audio_st)
1544 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1545 av_log(NULL, AV_LOG_INFO,
1546 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1547 get_master_clock(is),
1548 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1550 is->frame_drops_early + is->frame_drops_late,
1554 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1555 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1557 last_time = cur_time;
1562 /* allocate a picture (needs to do that in main thread to avoid
1563 potential locking problems */
1564 static void alloc_picture(VideoState *is)
1569 vp = &is->pictq.queue[is->pictq.windex];
1573 video_open(is, 0, vp);
1575 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1578 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1579 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1580 /* SDL allocates a buffer smaller than requested if the video
1581 * overlay hardware is unable to support the requested size. */
1582 av_log(NULL, AV_LOG_FATAL,
1583 "Error: the video system does not support an image\n"
1584 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1585 "to reduce the image size.\n", vp->width, vp->height );
1589 SDL_LockMutex(is->pictq.mutex);
1591 SDL_CondSignal(is->pictq.cond);
1592 SDL_UnlockMutex(is->pictq.mutex);
1595 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1596 int i, width, height;
1598 for (i = 0; i < 3; i++) {
1605 if (bmp->pitches[i] > width) {
1606 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1607 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1613 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1617 #if defined(DEBUG_SYNC) && 0
1618 printf("frame_type=%c pts=%0.3f\n",
1619 av_get_picture_type_char(src_frame->pict_type), pts);
1622 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1625 vp->sar = src_frame->sample_aspect_ratio;
1627 /* alloc or resize hardware picture buffer */
1628 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1629 vp->width != src_frame->width ||
1630 vp->height != src_frame->height) {
1635 vp->width = src_frame->width;
1636 vp->height = src_frame->height;
1638 /* the allocation must be done in the main thread to avoid
1639 locking problems. */
1640 event.type = FF_ALLOC_EVENT;
1641 event.user.data1 = is;
1642 SDL_PushEvent(&event);
1644 /* wait until the picture is allocated */
1645 SDL_LockMutex(is->pictq.mutex);
1646 while (!vp->allocated && !is->videoq.abort_request) {
1647 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1649 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1650 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1651 while (!vp->allocated && !is->abort_request) {
1652 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1655 SDL_UnlockMutex(is->pictq.mutex);
1657 if (is->videoq.abort_request)
1661 /* if the frame is not skipped, then display it */
1663 AVPicture pict = { { 0 } };
1665 /* get a pointer on the bitmap */
1666 SDL_LockYUVOverlay (vp->bmp);
1668 pict.data[0] = vp->bmp->pixels[0];
1669 pict.data[1] = vp->bmp->pixels[2];
1670 pict.data[2] = vp->bmp->pixels[1];
1672 pict.linesize[0] = vp->bmp->pitches[0];
1673 pict.linesize[1] = vp->bmp->pitches[2];
1674 pict.linesize[2] = vp->bmp->pitches[1];
1677 // FIXME use direct rendering
1678 av_picture_copy(&pict, (AVPicture *)src_frame,
1679 src_frame->format, vp->width, vp->height);
1682 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1684 const AVClass *class = sws_get_class();
1685 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1686 AV_OPT_SEARCH_FAKE_OBJ);
1687 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1693 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1694 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1695 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1696 if (!is->img_convert_ctx) {
1697 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1700 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1701 0, vp->height, pict.data, pict.linesize);
1703 /* workaround SDL PITCH_WORKAROUND */
1704 duplicate_right_border_pixels(vp->bmp);
1705 /* update the bitmap content */
1706 SDL_UnlockYUVOverlay(vp->bmp);
1709 vp->duration = duration;
1711 vp->serial = serial;
1713 /* now we can update the picture count */
1714 frame_queue_push(&is->pictq);
1719 static int get_video_frame(VideoState *is, AVFrame *frame)
1723 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1729 if (frame->pts != AV_NOPTS_VALUE)
1730 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1732 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1734 is->viddec_width = frame->width;
1735 is->viddec_height = frame->height;
1737 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1738 if (frame->pts != AV_NOPTS_VALUE) {
1739 double diff = dpts - get_master_clock(is);
1740 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1741 diff - is->frame_last_filter_delay < 0 &&
1742 is->viddec.pkt_serial == is->vidclk.serial &&
1743 is->videoq.nb_packets) {
1744 is->frame_drops_early++;
1745 av_frame_unref(frame);
1756 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1757 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1760 int nb_filters = graph->nb_filters;
1761 AVFilterInOut *outputs = NULL, *inputs = NULL;
1764 outputs = avfilter_inout_alloc();
1765 inputs = avfilter_inout_alloc();
1766 if (!outputs || !inputs) {
1767 ret = AVERROR(ENOMEM);
1771 outputs->name = av_strdup("in");
1772 outputs->filter_ctx = source_ctx;
1773 outputs->pad_idx = 0;
1774 outputs->next = NULL;
1776 inputs->name = av_strdup("out");
1777 inputs->filter_ctx = sink_ctx;
1778 inputs->pad_idx = 0;
1779 inputs->next = NULL;
1781 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1784 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1788 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1789 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1790 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1792 ret = avfilter_graph_config(graph, NULL);
1794 avfilter_inout_free(&outputs);
1795 avfilter_inout_free(&inputs);
1799 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1801 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1802 char sws_flags_str[512] = "";
1803 char buffersrc_args[256];
1805 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1806 AVCodecContext *codec = is->video_st->codec;
1807 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1808 AVDictionaryEntry *e = NULL;
1810 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1811 if (!strcmp(e->key, "sws_flags")) {
1812 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1814 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1816 if (strlen(sws_flags_str))
1817 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1819 graph->scale_sws_opts = av_strdup(sws_flags_str);
1821 snprintf(buffersrc_args, sizeof(buffersrc_args),
1822 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1823 frame->width, frame->height, frame->format,
1824 is->video_st->time_base.num, is->video_st->time_base.den,
1825 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1826 if (fr.num && fr.den)
1827 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1829 if ((ret = avfilter_graph_create_filter(&filt_src,
1830 avfilter_get_by_name("buffer"),
1831 "ffplay_buffer", buffersrc_args, NULL,
1835 ret = avfilter_graph_create_filter(&filt_out,
1836 avfilter_get_by_name("buffersink"),
1837 "ffplay_buffersink", NULL, NULL, graph);
1841 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1844 last_filter = filt_out;
1846 /* Note: this macro adds a filter before the lastly added filter, so the
1847 * processing order of the filters is in reverse */
1848 #define INSERT_FILT(name, arg) do { \
1849 AVFilterContext *filt_ctx; \
1851 ret = avfilter_graph_create_filter(&filt_ctx, \
1852 avfilter_get_by_name(name), \
1853 "ffplay_" name, arg, NULL, graph); \
1857 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1861 last_filter = filt_ctx; \
1864 /* SDL YUV code is not handling odd width/height for some driver
1865 * combinations, therefore we crop the picture to an even width/height. */
1866 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1869 double theta = get_rotation(is->video_st);
1871 if (fabs(theta - 90) < 1.0) {
1872 INSERT_FILT("transpose", "clock");
1873 } else if (fabs(theta - 180) < 1.0) {
1874 INSERT_FILT("hflip", NULL);
1875 INSERT_FILT("vflip", NULL);
1876 } else if (fabs(theta - 270) < 1.0) {
1877 INSERT_FILT("transpose", "cclock");
1878 } else if (fabs(theta) > 1.0) {
1879 char rotate_buf[64];
1880 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1881 INSERT_FILT("rotate", rotate_buf);
1885 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1888 is->in_video_filter = filt_src;
1889 is->out_video_filter = filt_out;
1895 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1897 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1898 int sample_rates[2] = { 0, -1 };
1899 int64_t channel_layouts[2] = { 0, -1 };
1900 int channels[2] = { 0, -1 };
1901 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1902 char aresample_swr_opts[512] = "";
1903 AVDictionaryEntry *e = NULL;
1904 char asrc_args[256];
1907 avfilter_graph_free(&is->agraph);
1908 if (!(is->agraph = avfilter_graph_alloc()))
1909 return AVERROR(ENOMEM);
1911 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1912 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1913 if (strlen(aresample_swr_opts))
1914 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1915 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1917 ret = snprintf(asrc_args, sizeof(asrc_args),
1918 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1919 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1920 is->audio_filter_src.channels,
1921 1, is->audio_filter_src.freq);
1922 if (is->audio_filter_src.channel_layout)
1923 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1924 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1926 ret = avfilter_graph_create_filter(&filt_asrc,
1927 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1928 asrc_args, NULL, is->agraph);
1933 ret = avfilter_graph_create_filter(&filt_asink,
1934 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1935 NULL, NULL, is->agraph);
1939 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1941 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1944 if (force_output_format) {
1945 channel_layouts[0] = is->audio_tgt.channel_layout;
1946 channels [0] = is->audio_tgt.channels;
1947 sample_rates [0] = is->audio_tgt.freq;
1948 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1950 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1952 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1954 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1959 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1962 is->in_audio_filter = filt_asrc;
1963 is->out_audio_filter = filt_asink;
1967 avfilter_graph_free(&is->agraph);
1970 #endif /* CONFIG_AVFILTER */
1972 static int audio_thread(void *arg)
1974 VideoState *is = arg;
1975 AVFrame *frame = av_frame_alloc();
1978 int last_serial = -1;
1979 int64_t dec_channel_layout;
1987 return AVERROR(ENOMEM);
1990 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1994 tb = (AVRational){1, frame->sample_rate};
1997 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2000 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2001 frame->format, av_frame_get_channels(frame)) ||
2002 is->audio_filter_src.channel_layout != dec_channel_layout ||
2003 is->audio_filter_src.freq != frame->sample_rate ||
2004 is->auddec.pkt_serial != last_serial;
2007 char buf1[1024], buf2[1024];
2008 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2009 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2010 av_log(NULL, AV_LOG_DEBUG,
2011 "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",
2012 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2013 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2015 is->audio_filter_src.fmt = frame->format;
2016 is->audio_filter_src.channels = av_frame_get_channels(frame);
2017 is->audio_filter_src.channel_layout = dec_channel_layout;
2018 is->audio_filter_src.freq = frame->sample_rate;
2019 last_serial = is->auddec.pkt_serial;
2021 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2025 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2028 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2029 tb = is->out_audio_filter->inputs[0]->time_base;
2031 if (!(af = frame_queue_peek_writable(&is->sampq)))
2034 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2035 af->pos = av_frame_get_pkt_pos(frame);
2036 af->serial = is->auddec.pkt_serial;
2037 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2039 av_frame_move_ref(af->frame, frame);
2040 frame_queue_push(&is->sampq);
2043 if (is->audioq.serial != is->auddec.pkt_serial)
2046 if (ret == AVERROR_EOF)
2047 is->auddec.finished = is->auddec.pkt_serial;
2050 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2053 avfilter_graph_free(&is->agraph);
2055 av_frame_free(&frame);
2059 static void decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2061 packet_queue_start(d->queue);
2062 d->decoder_tid = SDL_CreateThread(fn, arg);
2065 static int video_thread(void *arg)
2067 VideoState *is = arg;
2068 AVFrame *frame = av_frame_alloc();
2072 AVRational tb = is->video_st->time_base;
2073 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2076 AVFilterGraph *graph = avfilter_graph_alloc();
2077 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2080 enum AVPixelFormat last_format = -2;
2081 int last_serial = -1;
2082 int last_vfilter_idx = 0;
2084 av_frame_free(&frame);
2085 return AVERROR(ENOMEM);
2092 avfilter_graph_free(&graph);
2094 return AVERROR(ENOMEM);
2098 ret = get_video_frame(is, frame);
2105 if ( last_w != frame->width
2106 || last_h != frame->height
2107 || last_format != frame->format
2108 || last_serial != is->viddec.pkt_serial
2109 || last_vfilter_idx != is->vfilter_idx) {
2110 av_log(NULL, AV_LOG_DEBUG,
2111 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2113 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2114 frame->width, frame->height,
2115 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2116 avfilter_graph_free(&graph);
2117 graph = avfilter_graph_alloc();
2118 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2120 event.type = FF_QUIT_EVENT;
2121 event.user.data1 = is;
2122 SDL_PushEvent(&event);
2125 filt_in = is->in_video_filter;
2126 filt_out = is->out_video_filter;
2127 last_w = frame->width;
2128 last_h = frame->height;
2129 last_format = frame->format;
2130 last_serial = is->viddec.pkt_serial;
2131 last_vfilter_idx = is->vfilter_idx;
2132 frame_rate = filt_out->inputs[0]->frame_rate;
2135 ret = av_buffersrc_add_frame(filt_in, frame);
2140 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2142 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2144 if (ret == AVERROR_EOF)
2145 is->viddec.finished = is->viddec.pkt_serial;
2150 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2151 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2152 is->frame_last_filter_delay = 0;
2153 tb = filt_out->inputs[0]->time_base;
2155 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2156 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2157 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2158 av_frame_unref(frame);
2168 avfilter_graph_free(&graph);
2170 av_frame_free(&frame);
2174 static int subtitle_thread(void *arg)
2176 VideoState *is = arg;
2183 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2186 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2191 if (got_subtitle && sp->sub.format == 0) {
2192 if (sp->sub.pts != AV_NOPTS_VALUE)
2193 pts = sp->sub.pts / (double)AV_TIME_BASE;
2195 sp->serial = is->subdec.pkt_serial;
2197 for (i = 0; i < sp->sub.num_rects; i++)
2199 int in_w = sp->sub.rects[i]->w;
2200 int in_h = sp->sub.rects[i]->h;
2201 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2202 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2203 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2204 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2207 //can not use avpicture_alloc as it is not compatible with avsubtitle_free()
2208 av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);
2209 newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
2210 newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
2211 newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
2212 newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
2214 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2215 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2216 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2217 if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||
2218 !newpic.data[1] || !newpic.data[2]
2220 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2223 sws_scale(is->sub_convert_ctx,
2224 (void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,
2225 0, in_h, newpic.data, newpic.linesize);
2227 av_free(sp->sub.rects[i]->pict.data[0]);
2228 av_free(sp->sub.rects[i]->pict.data[1]);
2229 sp->sub.rects[i]->pict = newpic;
2230 sp->sub.rects[i]->w = out_w;
2231 sp->sub.rects[i]->h = out_h;
2232 sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2233 sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2236 /* now we can update the picture count */
2237 frame_queue_push(&is->subpq);
2238 } else if (got_subtitle) {
2239 avsubtitle_free(&sp->sub);
2245 /* copy samples for viewing in editor window */
2246 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2250 size = samples_size / sizeof(short);
2252 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2255 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2257 is->sample_array_index += len;
2258 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2259 is->sample_array_index = 0;
2264 /* return the wanted number of samples to get better sync if sync_type is video
2265 * or external master clock */
2266 static int synchronize_audio(VideoState *is, int nb_samples)
2268 int wanted_nb_samples = nb_samples;
2270 /* if not master, then we try to remove or add samples to correct the clock */
2271 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2272 double diff, avg_diff;
2273 int min_nb_samples, max_nb_samples;
2275 diff = get_clock(&is->audclk) - get_master_clock(is);
2277 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2278 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2279 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2280 /* not enough measures to have a correct estimate */
2281 is->audio_diff_avg_count++;
2283 /* estimate the A-V difference */
2284 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2286 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2287 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2288 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2289 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2290 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2292 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2293 diff, avg_diff, wanted_nb_samples - nb_samples,
2294 is->audio_clock, is->audio_diff_threshold);
2297 /* too big difference : may be initial PTS errors, so
2299 is->audio_diff_avg_count = 0;
2300 is->audio_diff_cum = 0;
2304 return wanted_nb_samples;
2308 * Decode one audio frame and return its uncompressed size.
2310 * The processed audio frame is decoded, converted if required, and
2311 * stored in is->audio_buf, with size in bytes given by the return
2314 static int audio_decode_frame(VideoState *is)
2316 int data_size, resampled_data_size;
2317 int64_t dec_channel_layout;
2318 av_unused double audio_clock0;
2319 int wanted_nb_samples;
2327 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2328 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2333 if (!(af = frame_queue_peek_readable(&is->sampq)))
2335 frame_queue_next(&is->sampq);
2336 } while (af->serial != is->audioq.serial);
2338 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2339 af->frame->nb_samples,
2340 af->frame->format, 1);
2342 dec_channel_layout =
2343 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2344 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2345 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2347 if (af->frame->format != is->audio_src.fmt ||
2348 dec_channel_layout != is->audio_src.channel_layout ||
2349 af->frame->sample_rate != is->audio_src.freq ||
2350 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2351 swr_free(&is->swr_ctx);
2352 is->swr_ctx = swr_alloc_set_opts(NULL,
2353 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2354 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2356 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2357 av_log(NULL, AV_LOG_ERROR,
2358 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2359 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2360 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2361 swr_free(&is->swr_ctx);
2364 is->audio_src.channel_layout = dec_channel_layout;
2365 is->audio_src.channels = av_frame_get_channels(af->frame);
2366 is->audio_src.freq = af->frame->sample_rate;
2367 is->audio_src.fmt = af->frame->format;
2371 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2372 uint8_t **out = &is->audio_buf1;
2373 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2374 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2377 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2380 if (wanted_nb_samples != af->frame->nb_samples) {
2381 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2382 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2383 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2387 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2388 if (!is->audio_buf1)
2389 return AVERROR(ENOMEM);
2390 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2392 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2395 if (len2 == out_count) {
2396 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2397 if (swr_init(is->swr_ctx) < 0)
2398 swr_free(&is->swr_ctx);
2400 is->audio_buf = is->audio_buf1;
2401 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2403 is->audio_buf = af->frame->data[0];
2404 resampled_data_size = data_size;
2407 audio_clock0 = is->audio_clock;
2408 /* update the audio clock with the pts */
2409 if (!isnan(af->pts))
2410 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2412 is->audio_clock = NAN;
2413 is->audio_clock_serial = af->serial;
2416 static double last_clock;
2417 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2418 is->audio_clock - last_clock,
2419 is->audio_clock, audio_clock0);
2420 last_clock = is->audio_clock;
2423 return resampled_data_size;
2426 /* prepare a new audio buffer */
2427 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2429 VideoState *is = opaque;
2430 int audio_size, len1;
2432 audio_callback_time = av_gettime_relative();
2435 if (is->audio_buf_index >= is->audio_buf_size) {
2436 audio_size = audio_decode_frame(is);
2437 if (audio_size < 0) {
2438 /* if error, just output silence */
2439 is->audio_buf = is->silence_buf;
2440 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2442 if (is->show_mode != SHOW_MODE_VIDEO)
2443 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2444 is->audio_buf_size = audio_size;
2446 is->audio_buf_index = 0;
2448 len1 = is->audio_buf_size - is->audio_buf_index;
2451 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2454 is->audio_buf_index += len1;
2456 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2457 /* Let's assume the audio driver that is used by SDL has two periods. */
2458 if (!isnan(is->audio_clock)) {
2459 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);
2460 sync_clock_to_slave(&is->extclk, &is->audclk);
2464 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2466 SDL_AudioSpec wanted_spec, spec;
2468 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2469 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2470 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2472 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2474 wanted_nb_channels = atoi(env);
2475 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2477 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2478 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2479 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2481 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2482 wanted_spec.channels = wanted_nb_channels;
2483 wanted_spec.freq = wanted_sample_rate;
2484 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2485 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2488 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2489 next_sample_rate_idx--;
2490 wanted_spec.format = AUDIO_S16SYS;
2491 wanted_spec.silence = 0;
2492 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2493 wanted_spec.callback = sdl_audio_callback;
2494 wanted_spec.userdata = opaque;
2495 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2496 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2497 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2498 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2499 if (!wanted_spec.channels) {
2500 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2501 wanted_spec.channels = wanted_nb_channels;
2502 if (!wanted_spec.freq) {
2503 av_log(NULL, AV_LOG_ERROR,
2504 "No more combinations to try, audio open failed\n");
2508 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2510 if (spec.format != AUDIO_S16SYS) {
2511 av_log(NULL, AV_LOG_ERROR,
2512 "SDL advised audio format %d is not supported!\n", spec.format);
2515 if (spec.channels != wanted_spec.channels) {
2516 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2517 if (!wanted_channel_layout) {
2518 av_log(NULL, AV_LOG_ERROR,
2519 "SDL advised channel count %d is not supported!\n", spec.channels);
2524 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2525 audio_hw_params->freq = spec.freq;
2526 audio_hw_params->channel_layout = wanted_channel_layout;
2527 audio_hw_params->channels = spec.channels;
2528 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2529 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);
2530 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2531 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2537 /* open a given stream. Return 0 if OK */
2538 static int stream_component_open(VideoState *is, int stream_index)
2540 AVFormatContext *ic = is->ic;
2541 AVCodecContext *avctx;
2543 const char *forced_codec_name = NULL;
2545 AVDictionaryEntry *t = NULL;
2546 int sample_rate, nb_channels;
2547 int64_t channel_layout;
2549 int stream_lowres = lowres;
2551 if (stream_index < 0 || stream_index >= ic->nb_streams)
2553 avctx = ic->streams[stream_index]->codec;
2555 codec = avcodec_find_decoder(avctx->codec_id);
2557 switch(avctx->codec_type){
2558 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2559 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2560 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2562 if (forced_codec_name)
2563 codec = avcodec_find_decoder_by_name(forced_codec_name);
2565 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2566 "No codec could be found with name '%s'\n", forced_codec_name);
2567 else av_log(NULL, AV_LOG_WARNING,
2568 "No codec could be found with id %d\n", avctx->codec_id);
2572 avctx->codec_id = codec->id;
2573 if(stream_lowres > av_codec_get_max_lowres(codec)){
2574 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2575 av_codec_get_max_lowres(codec));
2576 stream_lowres = av_codec_get_max_lowres(codec);
2578 av_codec_set_lowres(avctx, stream_lowres);
2580 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2582 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2583 if(codec->capabilities & AV_CODEC_CAP_DR1)
2584 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2586 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2587 if (!av_dict_get(opts, "threads", NULL, 0))
2588 av_dict_set(&opts, "threads", "auto", 0);
2590 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2591 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2592 av_dict_set(&opts, "refcounted_frames", "1", 0);
2593 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2596 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2597 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2598 ret = AVERROR_OPTION_NOT_FOUND;
2603 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2604 switch (avctx->codec_type) {
2605 case AVMEDIA_TYPE_AUDIO:
2610 is->audio_filter_src.freq = avctx->sample_rate;
2611 is->audio_filter_src.channels = avctx->channels;
2612 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2613 is->audio_filter_src.fmt = avctx->sample_fmt;
2614 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2616 link = is->out_audio_filter->inputs[0];
2617 sample_rate = link->sample_rate;
2618 nb_channels = link->channels;
2619 channel_layout = link->channel_layout;
2622 sample_rate = avctx->sample_rate;
2623 nb_channels = avctx->channels;
2624 channel_layout = avctx->channel_layout;
2627 /* prepare audio output */
2628 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2630 is->audio_hw_buf_size = ret;
2631 is->audio_src = is->audio_tgt;
2632 is->audio_buf_size = 0;
2633 is->audio_buf_index = 0;
2635 /* init averaging filter */
2636 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2637 is->audio_diff_avg_count = 0;
2638 /* since we do not have a precise anough audio fifo fullness,
2639 we correct audio sync only if larger than this threshold */
2640 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2642 is->audio_stream = stream_index;
2643 is->audio_st = ic->streams[stream_index];
2645 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2646 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2647 is->auddec.start_pts = is->audio_st->start_time;
2648 is->auddec.start_pts_tb = is->audio_st->time_base;
2650 decoder_start(&is->auddec, audio_thread, is);
2653 case AVMEDIA_TYPE_VIDEO:
2654 is->video_stream = stream_index;
2655 is->video_st = ic->streams[stream_index];
2657 is->viddec_width = avctx->width;
2658 is->viddec_height = avctx->height;
2660 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2661 decoder_start(&is->viddec, video_thread, is);
2662 is->queue_attachments_req = 1;
2664 case AVMEDIA_TYPE_SUBTITLE:
2665 is->subtitle_stream = stream_index;
2666 is->subtitle_st = ic->streams[stream_index];
2668 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2669 decoder_start(&is->subdec, subtitle_thread, is);
2676 av_dict_free(&opts);
2681 static void stream_component_close(VideoState *is, int stream_index)
2683 AVFormatContext *ic = is->ic;
2684 AVCodecContext *avctx;
2686 if (stream_index < 0 || stream_index >= ic->nb_streams)
2688 avctx = ic->streams[stream_index]->codec;
2690 switch (avctx->codec_type) {
2691 case AVMEDIA_TYPE_AUDIO:
2692 decoder_abort(&is->auddec, &is->sampq);
2694 decoder_destroy(&is->auddec);
2695 swr_free(&is->swr_ctx);
2696 av_freep(&is->audio_buf1);
2697 is->audio_buf1_size = 0;
2698 is->audio_buf = NULL;
2701 av_rdft_end(is->rdft);
2702 av_freep(&is->rdft_data);
2707 case AVMEDIA_TYPE_VIDEO:
2708 decoder_abort(&is->viddec, &is->pictq);
2709 decoder_destroy(&is->viddec);
2711 case AVMEDIA_TYPE_SUBTITLE:
2712 decoder_abort(&is->subdec, &is->subpq);
2713 decoder_destroy(&is->subdec);
2719 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2720 avcodec_close(avctx);
2721 switch (avctx->codec_type) {
2722 case AVMEDIA_TYPE_AUDIO:
2723 is->audio_st = NULL;
2724 is->audio_stream = -1;
2726 case AVMEDIA_TYPE_VIDEO:
2727 is->video_st = NULL;
2728 is->video_stream = -1;
2730 case AVMEDIA_TYPE_SUBTITLE:
2731 is->subtitle_st = NULL;
2732 is->subtitle_stream = -1;
2739 static int decode_interrupt_cb(void *ctx)
2741 VideoState *is = ctx;
2742 return is->abort_request;
2745 static int is_realtime(AVFormatContext *s)
2747 if( !strcmp(s->iformat->name, "rtp")
2748 || !strcmp(s->iformat->name, "rtsp")
2749 || !strcmp(s->iformat->name, "sdp")
2753 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2754 || !strncmp(s->filename, "udp:", 4)
2761 /* this thread gets the stream from the disk or the network */
2762 static int read_thread(void *arg)
2764 VideoState *is = arg;
2765 AVFormatContext *ic = NULL;
2767 int st_index[AVMEDIA_TYPE_NB];
2768 AVPacket pkt1, *pkt = &pkt1;
2769 int64_t stream_start_time;
2770 int pkt_in_play_range = 0;
2771 AVDictionaryEntry *t;
2772 AVDictionary **opts;
2773 int orig_nb_streams;
2774 SDL_mutex *wait_mutex = SDL_CreateMutex();
2775 int scan_all_pmts_set = 0;
2778 memset(st_index, -1, sizeof(st_index));
2779 is->last_video_stream = is->video_stream = -1;
2780 is->last_audio_stream = is->audio_stream = -1;
2781 is->last_subtitle_stream = is->subtitle_stream = -1;
2784 ic = avformat_alloc_context();
2786 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2787 ret = AVERROR(ENOMEM);
2790 ic->interrupt_callback.callback = decode_interrupt_cb;
2791 ic->interrupt_callback.opaque = is;
2792 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2793 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2794 scan_all_pmts_set = 1;
2796 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2798 print_error(is->filename, err);
2802 if (scan_all_pmts_set)
2803 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2805 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2806 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2807 ret = AVERROR_OPTION_NOT_FOUND;
2813 ic->flags |= AVFMT_FLAG_GENPTS;
2815 av_format_inject_global_side_data(ic);
2817 opts = setup_find_stream_info_opts(ic, codec_opts);
2818 orig_nb_streams = ic->nb_streams;
2820 err = avformat_find_stream_info(ic, opts);
2822 for (i = 0; i < orig_nb_streams; i++)
2823 av_dict_free(&opts[i]);
2827 av_log(NULL, AV_LOG_WARNING,
2828 "%s: could not find codec parameters\n", is->filename);
2834 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2836 if (seek_by_bytes < 0)
2837 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2839 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2841 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2842 window_title = av_asprintf("%s - %s", t->value, input_filename);
2844 /* if seeking requested, we execute it */
2845 if (start_time != AV_NOPTS_VALUE) {
2848 timestamp = start_time;
2849 /* add the stream start time */
2850 if (ic->start_time != AV_NOPTS_VALUE)
2851 timestamp += ic->start_time;
2852 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2854 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2855 is->filename, (double)timestamp / AV_TIME_BASE);
2859 is->realtime = is_realtime(ic);
2862 av_dump_format(ic, 0, is->filename, 0);
2864 for (i = 0; i < ic->nb_streams; i++) {
2865 AVStream *st = ic->streams[i];
2866 enum AVMediaType type = st->codec->codec_type;
2867 st->discard = AVDISCARD_ALL;
2868 if (wanted_stream_spec[type] && st_index[type] == -1)
2869 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2872 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2873 if (wanted_stream_spec[i] && st_index[i] == -1) {
2874 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));
2875 st_index[i] = INT_MAX;
2880 st_index[AVMEDIA_TYPE_VIDEO] =
2881 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2882 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2884 st_index[AVMEDIA_TYPE_AUDIO] =
2885 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2886 st_index[AVMEDIA_TYPE_AUDIO],
2887 st_index[AVMEDIA_TYPE_VIDEO],
2889 if (!video_disable && !subtitle_disable)
2890 st_index[AVMEDIA_TYPE_SUBTITLE] =
2891 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2892 st_index[AVMEDIA_TYPE_SUBTITLE],
2893 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2894 st_index[AVMEDIA_TYPE_AUDIO] :
2895 st_index[AVMEDIA_TYPE_VIDEO]),
2898 is->show_mode = show_mode;
2899 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2900 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2901 AVCodecContext *avctx = st->codec;
2902 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2904 set_default_window_size(avctx->width, avctx->height, sar);
2907 /* open the streams */
2908 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2909 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2913 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2914 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2916 if (is->show_mode == SHOW_MODE_NONE)
2917 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2919 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2920 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2923 if (is->video_stream < 0 && is->audio_stream < 0) {
2924 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2930 if (infinite_buffer < 0 && is->realtime)
2931 infinite_buffer = 1;
2934 if (is->abort_request)
2936 if (is->paused != is->last_paused) {
2937 is->last_paused = is->paused;
2939 is->read_pause_return = av_read_pause(ic);
2943 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2945 (!strcmp(ic->iformat->name, "rtsp") ||
2946 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2947 /* wait 10 ms to avoid trying to get another packet */
2954 int64_t seek_target = is->seek_pos;
2955 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2956 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2957 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2958 // of the seek_pos/seek_rel variables
2960 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2962 av_log(NULL, AV_LOG_ERROR,
2963 "%s: error while seeking\n", is->ic->filename);
2965 if (is->audio_stream >= 0) {
2966 packet_queue_flush(&is->audioq);
2967 packet_queue_put(&is->audioq, &flush_pkt);
2969 if (is->subtitle_stream >= 0) {
2970 packet_queue_flush(&is->subtitleq);
2971 packet_queue_put(&is->subtitleq, &flush_pkt);
2973 if (is->video_stream >= 0) {
2974 packet_queue_flush(&is->videoq);
2975 packet_queue_put(&is->videoq, &flush_pkt);
2977 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2978 set_clock(&is->extclk, NAN, 0);
2980 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2984 is->queue_attachments_req = 1;
2987 step_to_next_frame(is);
2989 if (is->queue_attachments_req) {
2990 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2992 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2994 packet_queue_put(&is->videoq, ©);
2995 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2997 is->queue_attachments_req = 0;
3000 /* if the queue are full, no need to read more */
3001 if (infinite_buffer<1 &&
3002 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3003 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3004 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3005 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3006 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3008 SDL_LockMutex(wait_mutex);
3009 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3010 SDL_UnlockMutex(wait_mutex);
3014 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3015 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3016 if (loop != 1 && (!loop || --loop)) {
3017 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3018 } else if (autoexit) {
3023 ret = av_read_frame(ic, pkt);
3025 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3026 if (is->video_stream >= 0)
3027 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3028 if (is->audio_stream >= 0)
3029 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3030 if (is->subtitle_stream >= 0)
3031 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3034 if (ic->pb && ic->pb->error)
3036 SDL_LockMutex(wait_mutex);
3037 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3038 SDL_UnlockMutex(wait_mutex);
3043 /* check if packet is in play range specified by user, then queue, otherwise discard */
3044 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3045 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3046 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3047 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3048 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3049 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3050 <= ((double)duration / 1000000);
3051 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3052 packet_queue_put(&is->audioq, pkt);
3053 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3054 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3055 packet_queue_put(&is->videoq, pkt);
3056 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3057 packet_queue_put(&is->subtitleq, pkt);
3059 av_free_packet(pkt);
3062 /* wait until the end */
3063 while (!is->abort_request) {
3069 /* close each stream */
3070 if (is->audio_stream >= 0)
3071 stream_component_close(is, is->audio_stream);
3072 if (is->video_stream >= 0)
3073 stream_component_close(is, is->video_stream);
3074 if (is->subtitle_stream >= 0)
3075 stream_component_close(is, is->subtitle_stream);
3077 avformat_close_input(&ic);
3084 event.type = FF_QUIT_EVENT;
3085 event.user.data1 = is;
3086 SDL_PushEvent(&event);
3088 SDL_DestroyMutex(wait_mutex);
3092 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3096 is = av_mallocz(sizeof(VideoState));
3099 av_strlcpy(is->filename, filename, sizeof(is->filename));
3100 is->iformat = iformat;
3104 /* start video display */
3105 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3107 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3109 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3112 packet_queue_init(&is->videoq);
3113 packet_queue_init(&is->audioq);
3114 packet_queue_init(&is->subtitleq);
3116 is->continue_read_thread = SDL_CreateCond();
3118 init_clock(&is->vidclk, &is->videoq.serial);
3119 init_clock(&is->audclk, &is->audioq.serial);
3120 init_clock(&is->extclk, &is->extclk.serial);
3121 is->audio_clock_serial = -1;
3122 is->av_sync_type = av_sync_type;
3123 is->read_tid = SDL_CreateThread(read_thread, is);
3124 if (!is->read_tid) {
3132 static void stream_cycle_channel(VideoState *is, int codec_type)
3134 AVFormatContext *ic = is->ic;
3135 int start_index, stream_index;
3138 AVProgram *p = NULL;
3139 int nb_streams = is->ic->nb_streams;
3141 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3142 start_index = is->last_video_stream;
3143 old_index = is->video_stream;
3144 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3145 start_index = is->last_audio_stream;
3146 old_index = is->audio_stream;
3148 start_index = is->last_subtitle_stream;
3149 old_index = is->subtitle_stream;
3151 stream_index = start_index;
3153 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3154 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3156 nb_streams = p->nb_stream_indexes;
3157 for (start_index = 0; start_index < nb_streams; start_index++)
3158 if (p->stream_index[start_index] == stream_index)
3160 if (start_index == nb_streams)
3162 stream_index = start_index;
3167 if (++stream_index >= nb_streams)
3169 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3172 is->last_subtitle_stream = -1;
3175 if (start_index == -1)
3179 if (stream_index == start_index)
3181 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3182 if (st->codec->codec_type == codec_type) {
3183 /* check that parameters are OK */
3184 switch (codec_type) {
3185 case AVMEDIA_TYPE_AUDIO:
3186 if (st->codec->sample_rate != 0 &&
3187 st->codec->channels != 0)
3190 case AVMEDIA_TYPE_VIDEO:
3191 case AVMEDIA_TYPE_SUBTITLE:
3199 if (p && stream_index != -1)
3200 stream_index = p->stream_index[stream_index];
3201 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3202 av_get_media_type_string(codec_type),
3206 stream_component_close(is, old_index);
3207 stream_component_open(is, stream_index);
3211 static void toggle_full_screen(VideoState *is)
3213 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3214 /* OS X needs to reallocate the SDL overlays */
3216 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3217 is->pictq.queue[i].reallocate = 1;
3219 is_full_screen = !is_full_screen;
3220 video_open(is, 1, NULL);
3223 static void toggle_audio_display(VideoState *is)
3225 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3226 int next = is->show_mode;
3228 next = (next + 1) % SHOW_MODE_NB;
3229 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3230 if (is->show_mode != next) {
3231 fill_rectangle(screen,
3232 is->xleft, is->ytop, is->width, is->height,
3234 is->force_refresh = 1;
3235 is->show_mode = next;
3239 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3240 double remaining_time = 0.0;
3242 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3243 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3247 if (remaining_time > 0.0)
3248 av_usleep((int64_t)(remaining_time * 1000000.0));
3249 remaining_time = REFRESH_RATE;
3250 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3251 video_refresh(is, &remaining_time);
3256 static void seek_chapter(VideoState *is, int incr)
3258 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3261 if (!is->ic->nb_chapters)
3264 /* find the current chapter */
3265 for (i = 0; i < is->ic->nb_chapters; i++) {
3266 AVChapter *ch = is->ic->chapters[i];
3267 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3275 if (i >= is->ic->nb_chapters)
3278 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3279 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3280 AV_TIME_BASE_Q), 0, 0);
3283 /* handle an event sent by the GUI */
3284 static void event_loop(VideoState *cur_stream)
3287 double incr, pos, frac;
3291 refresh_loop_wait_event(cur_stream, &event);
3292 switch (event.type) {
3294 if (exit_on_keydown) {
3295 do_exit(cur_stream);
3298 switch (event.key.keysym.sym) {
3301 do_exit(cur_stream);
3304 toggle_full_screen(cur_stream);
3305 cur_stream->force_refresh = 1;
3309 toggle_pause(cur_stream);
3311 case SDLK_s: // S: Step to next frame
3312 step_to_next_frame(cur_stream);
3315 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3318 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3321 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3322 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3323 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3326 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3330 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3331 if (++cur_stream->vfilter_idx >= nb_vfilters)
3332 cur_stream->vfilter_idx = 0;
3334 cur_stream->vfilter_idx = 0;
3335 toggle_audio_display(cur_stream);
3338 toggle_audio_display(cur_stream);
3342 if (cur_stream->ic->nb_chapters <= 1) {
3346 seek_chapter(cur_stream, 1);
3349 if (cur_stream->ic->nb_chapters <= 1) {
3353 seek_chapter(cur_stream, -1);
3367 if (seek_by_bytes) {
3369 if (pos < 0 && cur_stream->video_stream >= 0)
3370 pos = frame_queue_last_pos(&cur_stream->pictq);
3371 if (pos < 0 && cur_stream->audio_stream >= 0)
3372 pos = frame_queue_last_pos(&cur_stream->sampq);
3374 pos = avio_tell(cur_stream->ic->pb);
3375 if (cur_stream->ic->bit_rate)
3376 incr *= cur_stream->ic->bit_rate / 8.0;
3380 stream_seek(cur_stream, pos, incr, 1);
3382 pos = get_master_clock(cur_stream);
3384 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3386 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3387 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3388 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3395 case SDL_VIDEOEXPOSE:
3396 cur_stream->force_refresh = 1;
3398 case SDL_MOUSEBUTTONDOWN:
3399 if (exit_on_mousedown) {
3400 do_exit(cur_stream);
3403 case SDL_MOUSEMOTION:
3404 if (cursor_hidden) {
3408 cursor_last_shown = av_gettime_relative();
3409 if (event.type == SDL_MOUSEBUTTONDOWN) {
3412 if (event.motion.state != SDL_PRESSED)
3416 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3417 uint64_t size = avio_size(cur_stream->ic->pb);
3418 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3422 int tns, thh, tmm, tss;
3423 tns = cur_stream->ic->duration / 1000000LL;
3425 tmm = (tns % 3600) / 60;
3427 frac = x / cur_stream->width;
3430 mm = (ns % 3600) / 60;
3432 av_log(NULL, AV_LOG_INFO,
3433 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3434 hh, mm, ss, thh, tmm, tss);
3435 ts = frac * cur_stream->ic->duration;
3436 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3437 ts += cur_stream->ic->start_time;
3438 stream_seek(cur_stream, ts, 0, 0);
3441 case SDL_VIDEORESIZE:
3442 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3443 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3445 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3446 do_exit(cur_stream);
3448 screen_width = cur_stream->width = screen->w;
3449 screen_height = cur_stream->height = screen->h;
3450 cur_stream->force_refresh = 1;
3454 do_exit(cur_stream);
3456 case FF_ALLOC_EVENT:
3457 alloc_picture(event.user.data1);
3465 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3467 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3468 return opt_default(NULL, "video_size", arg);
3471 static int opt_width(void *optctx, const char *opt, const char *arg)
3473 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3477 static int opt_height(void *optctx, const char *opt, const char *arg)
3479 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3483 static int opt_format(void *optctx, const char *opt, const char *arg)
3485 file_iformat = av_find_input_format(arg);
3486 if (!file_iformat) {
3487 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3488 return AVERROR(EINVAL);
3493 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3495 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3496 return opt_default(NULL, "pixel_format", arg);
3499 static int opt_sync(void *optctx, const char *opt, const char *arg)
3501 if (!strcmp(arg, "audio"))
3502 av_sync_type = AV_SYNC_AUDIO_MASTER;
3503 else if (!strcmp(arg, "video"))
3504 av_sync_type = AV_SYNC_VIDEO_MASTER;
3505 else if (!strcmp(arg, "ext"))
3506 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3508 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3514 static int opt_seek(void *optctx, const char *opt, const char *arg)
3516 start_time = parse_time_or_die(opt, arg, 1);
3520 static int opt_duration(void *optctx, const char *opt, const char *arg)
3522 duration = parse_time_or_die(opt, arg, 1);
3526 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3528 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3529 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3530 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3531 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3535 static void opt_input_file(void *optctx, const char *filename)
3537 if (input_filename) {
3538 av_log(NULL, AV_LOG_FATAL,
3539 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3540 filename, input_filename);
3543 if (!strcmp(filename, "-"))
3545 input_filename = filename;
3548 static int opt_codec(void *optctx, const char *opt, const char *arg)
3550 const char *spec = strchr(opt, ':');
3552 av_log(NULL, AV_LOG_ERROR,
3553 "No media specifier was specified in '%s' in option '%s'\n",
3555 return AVERROR(EINVAL);
3559 case 'a' : audio_codec_name = arg; break;
3560 case 's' : subtitle_codec_name = arg; break;
3561 case 'v' : video_codec_name = arg; break;
3563 av_log(NULL, AV_LOG_ERROR,
3564 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3565 return AVERROR(EINVAL);
3572 static const OptionDef options[] = {
3573 #include "cmdutils_common_opts.h"
3574 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3575 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3576 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3577 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3578 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3579 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3580 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3581 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3582 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3583 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3584 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3585 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3586 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3587 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3588 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3589 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3590 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3591 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3592 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3593 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3594 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3595 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3596 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3597 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3598 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3599 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3600 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3601 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3602 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3604 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3605 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3607 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3608 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3609 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3610 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3611 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3612 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3613 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3614 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3615 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3619 static void show_usage(void)
3621 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3622 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3623 av_log(NULL, AV_LOG_INFO, "\n");
3626 void show_help_default(const char *opt, const char *arg)
3628 av_log_set_callback(log_callback_help);
3630 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3631 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3633 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3634 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3635 #if !CONFIG_AVFILTER
3636 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3638 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3640 printf("\nWhile playing:\n"
3642 "f toggle full screen\n"
3644 "a cycle audio channel in the current program\n"
3645 "v cycle video channel\n"
3646 "t cycle subtitle channel in the current program\n"
3648 "w cycle video filters or show modes\n"
3649 "s activate frame-step mode\n"
3650 "left/right seek backward/forward 10 seconds\n"
3651 "down/up seek backward/forward 1 minute\n"
3652 "page down/page up seek backward/forward 10 minutes\n"
3653 "mouse click seek to percentage in file corresponding to fraction of width\n"
3657 static int lockmgr(void **mtx, enum AVLockOp op)
3660 case AV_LOCK_CREATE:
3661 *mtx = SDL_CreateMutex();
3665 case AV_LOCK_OBTAIN:
3666 return !!SDL_LockMutex(*mtx);
3667 case AV_LOCK_RELEASE:
3668 return !!SDL_UnlockMutex(*mtx);
3669 case AV_LOCK_DESTROY:
3670 SDL_DestroyMutex(*mtx);
3676 /* Called from the main */
3677 int main(int argc, char **argv)
3681 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3683 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3684 parse_loglevel(argc, argv, options);
3686 /* register all codecs, demux and protocols */
3688 avdevice_register_all();
3691 avfilter_register_all();
3694 avformat_network_init();
3698 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3699 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3701 show_banner(argc, argv, options);
3703 parse_options(NULL, argc, argv, options, opt_input_file);
3705 if (!input_filename) {
3707 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3708 av_log(NULL, AV_LOG_FATAL,
3709 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3713 if (display_disable) {
3716 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3718 flags &= ~SDL_INIT_AUDIO;
3719 if (display_disable)
3720 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3721 #if !defined(_WIN32) && !defined(__APPLE__)
3722 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3724 if (SDL_Init (flags)) {
3725 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3726 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3730 if (!display_disable) {
3731 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3732 fs_screen_width = vi->current_w;
3733 fs_screen_height = vi->current_h;
3736 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3737 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3738 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3740 if (av_lockmgr_register(lockmgr)) {
3741 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3745 av_init_packet(&flush_pkt);
3746 flush_pkt.data = (uint8_t *)&flush_pkt;
3748 is = stream_open(input_filename, file_iformat);
3750 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");