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);
2581 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2584 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2586 if(codec->capabilities & AV_CODEC_CAP_DR1)
2587 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2590 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2591 if (!av_dict_get(opts, "threads", NULL, 0))
2592 av_dict_set(&opts, "threads", "auto", 0);
2594 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2595 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2596 av_dict_set(&opts, "refcounted_frames", "1", 0);
2597 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2600 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2601 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2602 ret = AVERROR_OPTION_NOT_FOUND;
2607 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2608 switch (avctx->codec_type) {
2609 case AVMEDIA_TYPE_AUDIO:
2614 is->audio_filter_src.freq = avctx->sample_rate;
2615 is->audio_filter_src.channels = avctx->channels;
2616 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2617 is->audio_filter_src.fmt = avctx->sample_fmt;
2618 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2620 link = is->out_audio_filter->inputs[0];
2621 sample_rate = link->sample_rate;
2622 nb_channels = link->channels;
2623 channel_layout = link->channel_layout;
2626 sample_rate = avctx->sample_rate;
2627 nb_channels = avctx->channels;
2628 channel_layout = avctx->channel_layout;
2631 /* prepare audio output */
2632 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2634 is->audio_hw_buf_size = ret;
2635 is->audio_src = is->audio_tgt;
2636 is->audio_buf_size = 0;
2637 is->audio_buf_index = 0;
2639 /* init averaging filter */
2640 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2641 is->audio_diff_avg_count = 0;
2642 /* since we do not have a precise anough audio fifo fullness,
2643 we correct audio sync only if larger than this threshold */
2644 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2646 is->audio_stream = stream_index;
2647 is->audio_st = ic->streams[stream_index];
2649 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2650 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2651 is->auddec.start_pts = is->audio_st->start_time;
2652 is->auddec.start_pts_tb = is->audio_st->time_base;
2654 decoder_start(&is->auddec, audio_thread, is);
2657 case AVMEDIA_TYPE_VIDEO:
2658 is->video_stream = stream_index;
2659 is->video_st = ic->streams[stream_index];
2661 is->viddec_width = avctx->width;
2662 is->viddec_height = avctx->height;
2664 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2665 decoder_start(&is->viddec, video_thread, is);
2666 is->queue_attachments_req = 1;
2668 case AVMEDIA_TYPE_SUBTITLE:
2669 is->subtitle_stream = stream_index;
2670 is->subtitle_st = ic->streams[stream_index];
2672 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2673 decoder_start(&is->subdec, subtitle_thread, is);
2680 av_dict_free(&opts);
2685 static void stream_component_close(VideoState *is, int stream_index)
2687 AVFormatContext *ic = is->ic;
2688 AVCodecContext *avctx;
2690 if (stream_index < 0 || stream_index >= ic->nb_streams)
2692 avctx = ic->streams[stream_index]->codec;
2694 switch (avctx->codec_type) {
2695 case AVMEDIA_TYPE_AUDIO:
2696 decoder_abort(&is->auddec, &is->sampq);
2698 decoder_destroy(&is->auddec);
2699 swr_free(&is->swr_ctx);
2700 av_freep(&is->audio_buf1);
2701 is->audio_buf1_size = 0;
2702 is->audio_buf = NULL;
2705 av_rdft_end(is->rdft);
2706 av_freep(&is->rdft_data);
2711 case AVMEDIA_TYPE_VIDEO:
2712 decoder_abort(&is->viddec, &is->pictq);
2713 decoder_destroy(&is->viddec);
2715 case AVMEDIA_TYPE_SUBTITLE:
2716 decoder_abort(&is->subdec, &is->subpq);
2717 decoder_destroy(&is->subdec);
2723 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2724 avcodec_close(avctx);
2725 switch (avctx->codec_type) {
2726 case AVMEDIA_TYPE_AUDIO:
2727 is->audio_st = NULL;
2728 is->audio_stream = -1;
2730 case AVMEDIA_TYPE_VIDEO:
2731 is->video_st = NULL;
2732 is->video_stream = -1;
2734 case AVMEDIA_TYPE_SUBTITLE:
2735 is->subtitle_st = NULL;
2736 is->subtitle_stream = -1;
2743 static int decode_interrupt_cb(void *ctx)
2745 VideoState *is = ctx;
2746 return is->abort_request;
2749 static int is_realtime(AVFormatContext *s)
2751 if( !strcmp(s->iformat->name, "rtp")
2752 || !strcmp(s->iformat->name, "rtsp")
2753 || !strcmp(s->iformat->name, "sdp")
2757 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2758 || !strncmp(s->filename, "udp:", 4)
2765 /* this thread gets the stream from the disk or the network */
2766 static int read_thread(void *arg)
2768 VideoState *is = arg;
2769 AVFormatContext *ic = NULL;
2771 int st_index[AVMEDIA_TYPE_NB];
2772 AVPacket pkt1, *pkt = &pkt1;
2773 int64_t stream_start_time;
2774 int pkt_in_play_range = 0;
2775 AVDictionaryEntry *t;
2776 AVDictionary **opts;
2777 int orig_nb_streams;
2778 SDL_mutex *wait_mutex = SDL_CreateMutex();
2779 int scan_all_pmts_set = 0;
2782 memset(st_index, -1, sizeof(st_index));
2783 is->last_video_stream = is->video_stream = -1;
2784 is->last_audio_stream = is->audio_stream = -1;
2785 is->last_subtitle_stream = is->subtitle_stream = -1;
2788 ic = avformat_alloc_context();
2790 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2791 ret = AVERROR(ENOMEM);
2794 ic->interrupt_callback.callback = decode_interrupt_cb;
2795 ic->interrupt_callback.opaque = is;
2796 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2797 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2798 scan_all_pmts_set = 1;
2800 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2802 print_error(is->filename, err);
2806 if (scan_all_pmts_set)
2807 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2809 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2810 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2811 ret = AVERROR_OPTION_NOT_FOUND;
2817 ic->flags |= AVFMT_FLAG_GENPTS;
2819 av_format_inject_global_side_data(ic);
2821 opts = setup_find_stream_info_opts(ic, codec_opts);
2822 orig_nb_streams = ic->nb_streams;
2824 err = avformat_find_stream_info(ic, opts);
2826 for (i = 0; i < orig_nb_streams; i++)
2827 av_dict_free(&opts[i]);
2831 av_log(NULL, AV_LOG_WARNING,
2832 "%s: could not find codec parameters\n", is->filename);
2838 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2840 if (seek_by_bytes < 0)
2841 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2843 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2845 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2846 window_title = av_asprintf("%s - %s", t->value, input_filename);
2848 /* if seeking requested, we execute it */
2849 if (start_time != AV_NOPTS_VALUE) {
2852 timestamp = start_time;
2853 /* add the stream start time */
2854 if (ic->start_time != AV_NOPTS_VALUE)
2855 timestamp += ic->start_time;
2856 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2858 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2859 is->filename, (double)timestamp / AV_TIME_BASE);
2863 is->realtime = is_realtime(ic);
2866 av_dump_format(ic, 0, is->filename, 0);
2868 for (i = 0; i < ic->nb_streams; i++) {
2869 AVStream *st = ic->streams[i];
2870 enum AVMediaType type = st->codec->codec_type;
2871 st->discard = AVDISCARD_ALL;
2872 if (wanted_stream_spec[type] && st_index[type] == -1)
2873 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2876 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2877 if (wanted_stream_spec[i] && st_index[i] == -1) {
2878 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));
2879 st_index[i] = INT_MAX;
2884 st_index[AVMEDIA_TYPE_VIDEO] =
2885 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2886 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2888 st_index[AVMEDIA_TYPE_AUDIO] =
2889 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2890 st_index[AVMEDIA_TYPE_AUDIO],
2891 st_index[AVMEDIA_TYPE_VIDEO],
2893 if (!video_disable && !subtitle_disable)
2894 st_index[AVMEDIA_TYPE_SUBTITLE] =
2895 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2896 st_index[AVMEDIA_TYPE_SUBTITLE],
2897 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2898 st_index[AVMEDIA_TYPE_AUDIO] :
2899 st_index[AVMEDIA_TYPE_VIDEO]),
2902 is->show_mode = show_mode;
2903 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2904 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2905 AVCodecContext *avctx = st->codec;
2906 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2908 set_default_window_size(avctx->width, avctx->height, sar);
2911 /* open the streams */
2912 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2913 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2917 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2918 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2920 if (is->show_mode == SHOW_MODE_NONE)
2921 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2923 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2924 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2927 if (is->video_stream < 0 && is->audio_stream < 0) {
2928 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2934 if (infinite_buffer < 0 && is->realtime)
2935 infinite_buffer = 1;
2938 if (is->abort_request)
2940 if (is->paused != is->last_paused) {
2941 is->last_paused = is->paused;
2943 is->read_pause_return = av_read_pause(ic);
2947 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2949 (!strcmp(ic->iformat->name, "rtsp") ||
2950 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2951 /* wait 10 ms to avoid trying to get another packet */
2958 int64_t seek_target = is->seek_pos;
2959 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2960 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2961 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2962 // of the seek_pos/seek_rel variables
2964 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2966 av_log(NULL, AV_LOG_ERROR,
2967 "%s: error while seeking\n", is->ic->filename);
2969 if (is->audio_stream >= 0) {
2970 packet_queue_flush(&is->audioq);
2971 packet_queue_put(&is->audioq, &flush_pkt);
2973 if (is->subtitle_stream >= 0) {
2974 packet_queue_flush(&is->subtitleq);
2975 packet_queue_put(&is->subtitleq, &flush_pkt);
2977 if (is->video_stream >= 0) {
2978 packet_queue_flush(&is->videoq);
2979 packet_queue_put(&is->videoq, &flush_pkt);
2981 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2982 set_clock(&is->extclk, NAN, 0);
2984 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2988 is->queue_attachments_req = 1;
2991 step_to_next_frame(is);
2993 if (is->queue_attachments_req) {
2994 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2996 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2998 packet_queue_put(&is->videoq, ©);
2999 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3001 is->queue_attachments_req = 0;
3004 /* if the queue are full, no need to read more */
3005 if (infinite_buffer<1 &&
3006 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3007 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3008 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3009 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3010 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3012 SDL_LockMutex(wait_mutex);
3013 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3014 SDL_UnlockMutex(wait_mutex);
3018 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3019 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3020 if (loop != 1 && (!loop || --loop)) {
3021 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3022 } else if (autoexit) {
3027 ret = av_read_frame(ic, pkt);
3029 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3030 if (is->video_stream >= 0)
3031 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3032 if (is->audio_stream >= 0)
3033 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3034 if (is->subtitle_stream >= 0)
3035 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3038 if (ic->pb && ic->pb->error)
3040 SDL_LockMutex(wait_mutex);
3041 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3042 SDL_UnlockMutex(wait_mutex);
3047 /* check if packet is in play range specified by user, then queue, otherwise discard */
3048 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3049 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3050 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3051 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3052 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3053 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3054 <= ((double)duration / 1000000);
3055 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3056 packet_queue_put(&is->audioq, pkt);
3057 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3058 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3059 packet_queue_put(&is->videoq, pkt);
3060 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3061 packet_queue_put(&is->subtitleq, pkt);
3063 av_free_packet(pkt);
3066 /* wait until the end */
3067 while (!is->abort_request) {
3073 /* close each stream */
3074 if (is->audio_stream >= 0)
3075 stream_component_close(is, is->audio_stream);
3076 if (is->video_stream >= 0)
3077 stream_component_close(is, is->video_stream);
3078 if (is->subtitle_stream >= 0)
3079 stream_component_close(is, is->subtitle_stream);
3081 avformat_close_input(&ic);
3088 event.type = FF_QUIT_EVENT;
3089 event.user.data1 = is;
3090 SDL_PushEvent(&event);
3092 SDL_DestroyMutex(wait_mutex);
3096 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3100 is = av_mallocz(sizeof(VideoState));
3103 av_strlcpy(is->filename, filename, sizeof(is->filename));
3104 is->iformat = iformat;
3108 /* start video display */
3109 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3111 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3113 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3116 packet_queue_init(&is->videoq);
3117 packet_queue_init(&is->audioq);
3118 packet_queue_init(&is->subtitleq);
3120 is->continue_read_thread = SDL_CreateCond();
3122 init_clock(&is->vidclk, &is->videoq.serial);
3123 init_clock(&is->audclk, &is->audioq.serial);
3124 init_clock(&is->extclk, &is->extclk.serial);
3125 is->audio_clock_serial = -1;
3126 is->av_sync_type = av_sync_type;
3127 is->read_tid = SDL_CreateThread(read_thread, is);
3128 if (!is->read_tid) {
3136 static void stream_cycle_channel(VideoState *is, int codec_type)
3138 AVFormatContext *ic = is->ic;
3139 int start_index, stream_index;
3142 AVProgram *p = NULL;
3143 int nb_streams = is->ic->nb_streams;
3145 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3146 start_index = is->last_video_stream;
3147 old_index = is->video_stream;
3148 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3149 start_index = is->last_audio_stream;
3150 old_index = is->audio_stream;
3152 start_index = is->last_subtitle_stream;
3153 old_index = is->subtitle_stream;
3155 stream_index = start_index;
3157 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3158 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3160 nb_streams = p->nb_stream_indexes;
3161 for (start_index = 0; start_index < nb_streams; start_index++)
3162 if (p->stream_index[start_index] == stream_index)
3164 if (start_index == nb_streams)
3166 stream_index = start_index;
3171 if (++stream_index >= nb_streams)
3173 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3176 is->last_subtitle_stream = -1;
3179 if (start_index == -1)
3183 if (stream_index == start_index)
3185 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3186 if (st->codec->codec_type == codec_type) {
3187 /* check that parameters are OK */
3188 switch (codec_type) {
3189 case AVMEDIA_TYPE_AUDIO:
3190 if (st->codec->sample_rate != 0 &&
3191 st->codec->channels != 0)
3194 case AVMEDIA_TYPE_VIDEO:
3195 case AVMEDIA_TYPE_SUBTITLE:
3203 if (p && stream_index != -1)
3204 stream_index = p->stream_index[stream_index];
3205 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3206 av_get_media_type_string(codec_type),
3210 stream_component_close(is, old_index);
3211 stream_component_open(is, stream_index);
3215 static void toggle_full_screen(VideoState *is)
3217 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3218 /* OS X needs to reallocate the SDL overlays */
3220 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3221 is->pictq.queue[i].reallocate = 1;
3223 is_full_screen = !is_full_screen;
3224 video_open(is, 1, NULL);
3227 static void toggle_audio_display(VideoState *is)
3229 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3230 int next = is->show_mode;
3232 next = (next + 1) % SHOW_MODE_NB;
3233 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3234 if (is->show_mode != next) {
3235 fill_rectangle(screen,
3236 is->xleft, is->ytop, is->width, is->height,
3238 is->force_refresh = 1;
3239 is->show_mode = next;
3243 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3244 double remaining_time = 0.0;
3246 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3247 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3251 if (remaining_time > 0.0)
3252 av_usleep((int64_t)(remaining_time * 1000000.0));
3253 remaining_time = REFRESH_RATE;
3254 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3255 video_refresh(is, &remaining_time);
3260 static void seek_chapter(VideoState *is, int incr)
3262 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3265 if (!is->ic->nb_chapters)
3268 /* find the current chapter */
3269 for (i = 0; i < is->ic->nb_chapters; i++) {
3270 AVChapter *ch = is->ic->chapters[i];
3271 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3279 if (i >= is->ic->nb_chapters)
3282 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3283 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3284 AV_TIME_BASE_Q), 0, 0);
3287 /* handle an event sent by the GUI */
3288 static void event_loop(VideoState *cur_stream)
3291 double incr, pos, frac;
3295 refresh_loop_wait_event(cur_stream, &event);
3296 switch (event.type) {
3298 if (exit_on_keydown) {
3299 do_exit(cur_stream);
3302 switch (event.key.keysym.sym) {
3305 do_exit(cur_stream);
3308 toggle_full_screen(cur_stream);
3309 cur_stream->force_refresh = 1;
3313 toggle_pause(cur_stream);
3315 case SDLK_s: // S: Step to next frame
3316 step_to_next_frame(cur_stream);
3319 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3322 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3325 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3326 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3327 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3330 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3334 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3335 if (++cur_stream->vfilter_idx >= nb_vfilters)
3336 cur_stream->vfilter_idx = 0;
3338 cur_stream->vfilter_idx = 0;
3339 toggle_audio_display(cur_stream);
3342 toggle_audio_display(cur_stream);
3346 if (cur_stream->ic->nb_chapters <= 1) {
3350 seek_chapter(cur_stream, 1);
3353 if (cur_stream->ic->nb_chapters <= 1) {
3357 seek_chapter(cur_stream, -1);
3371 if (seek_by_bytes) {
3373 if (pos < 0 && cur_stream->video_stream >= 0)
3374 pos = frame_queue_last_pos(&cur_stream->pictq);
3375 if (pos < 0 && cur_stream->audio_stream >= 0)
3376 pos = frame_queue_last_pos(&cur_stream->sampq);
3378 pos = avio_tell(cur_stream->ic->pb);
3379 if (cur_stream->ic->bit_rate)
3380 incr *= cur_stream->ic->bit_rate / 8.0;
3384 stream_seek(cur_stream, pos, incr, 1);
3386 pos = get_master_clock(cur_stream);
3388 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3390 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3391 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3392 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3399 case SDL_VIDEOEXPOSE:
3400 cur_stream->force_refresh = 1;
3402 case SDL_MOUSEBUTTONDOWN:
3403 if (exit_on_mousedown) {
3404 do_exit(cur_stream);
3407 case SDL_MOUSEMOTION:
3408 if (cursor_hidden) {
3412 cursor_last_shown = av_gettime_relative();
3413 if (event.type == SDL_MOUSEBUTTONDOWN) {
3416 if (event.motion.state != SDL_PRESSED)
3420 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3421 uint64_t size = avio_size(cur_stream->ic->pb);
3422 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3426 int tns, thh, tmm, tss;
3427 tns = cur_stream->ic->duration / 1000000LL;
3429 tmm = (tns % 3600) / 60;
3431 frac = x / cur_stream->width;
3434 mm = (ns % 3600) / 60;
3436 av_log(NULL, AV_LOG_INFO,
3437 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3438 hh, mm, ss, thh, tmm, tss);
3439 ts = frac * cur_stream->ic->duration;
3440 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3441 ts += cur_stream->ic->start_time;
3442 stream_seek(cur_stream, ts, 0, 0);
3445 case SDL_VIDEORESIZE:
3446 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3447 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3449 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3450 do_exit(cur_stream);
3452 screen_width = cur_stream->width = screen->w;
3453 screen_height = cur_stream->height = screen->h;
3454 cur_stream->force_refresh = 1;
3458 do_exit(cur_stream);
3460 case FF_ALLOC_EVENT:
3461 alloc_picture(event.user.data1);
3469 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3471 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3472 return opt_default(NULL, "video_size", arg);
3475 static int opt_width(void *optctx, const char *opt, const char *arg)
3477 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3481 static int opt_height(void *optctx, const char *opt, const char *arg)
3483 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3487 static int opt_format(void *optctx, const char *opt, const char *arg)
3489 file_iformat = av_find_input_format(arg);
3490 if (!file_iformat) {
3491 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3492 return AVERROR(EINVAL);
3497 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3499 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3500 return opt_default(NULL, "pixel_format", arg);
3503 static int opt_sync(void *optctx, const char *opt, const char *arg)
3505 if (!strcmp(arg, "audio"))
3506 av_sync_type = AV_SYNC_AUDIO_MASTER;
3507 else if (!strcmp(arg, "video"))
3508 av_sync_type = AV_SYNC_VIDEO_MASTER;
3509 else if (!strcmp(arg, "ext"))
3510 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3512 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3518 static int opt_seek(void *optctx, const char *opt, const char *arg)
3520 start_time = parse_time_or_die(opt, arg, 1);
3524 static int opt_duration(void *optctx, const char *opt, const char *arg)
3526 duration = parse_time_or_die(opt, arg, 1);
3530 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3532 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3533 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3534 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3535 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3539 static void opt_input_file(void *optctx, const char *filename)
3541 if (input_filename) {
3542 av_log(NULL, AV_LOG_FATAL,
3543 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3544 filename, input_filename);
3547 if (!strcmp(filename, "-"))
3549 input_filename = filename;
3552 static int opt_codec(void *optctx, const char *opt, const char *arg)
3554 const char *spec = strchr(opt, ':');
3556 av_log(NULL, AV_LOG_ERROR,
3557 "No media specifier was specified in '%s' in option '%s'\n",
3559 return AVERROR(EINVAL);
3563 case 'a' : audio_codec_name = arg; break;
3564 case 's' : subtitle_codec_name = arg; break;
3565 case 'v' : video_codec_name = arg; break;
3567 av_log(NULL, AV_LOG_ERROR,
3568 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3569 return AVERROR(EINVAL);
3576 static const OptionDef options[] = {
3577 #include "cmdutils_common_opts.h"
3578 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3579 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3580 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3581 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3582 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3583 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3584 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3585 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3586 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3587 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3588 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3589 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3590 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3591 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3592 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3593 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3594 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3595 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3596 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3597 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3598 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3599 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3600 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3601 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3602 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3603 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3604 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3605 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3606 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3608 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3609 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3611 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3612 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3613 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3614 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3615 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3616 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3617 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3618 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3619 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3623 static void show_usage(void)
3625 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3626 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3627 av_log(NULL, AV_LOG_INFO, "\n");
3630 void show_help_default(const char *opt, const char *arg)
3632 av_log_set_callback(log_callback_help);
3634 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3635 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3637 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3638 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3639 #if !CONFIG_AVFILTER
3640 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3642 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3644 printf("\nWhile playing:\n"
3646 "f toggle full screen\n"
3648 "a cycle audio channel in the current program\n"
3649 "v cycle video channel\n"
3650 "t cycle subtitle channel in the current program\n"
3652 "w cycle video filters or show modes\n"
3653 "s activate frame-step mode\n"
3654 "left/right seek backward/forward 10 seconds\n"
3655 "down/up seek backward/forward 1 minute\n"
3656 "page down/page up seek backward/forward 10 minutes\n"
3657 "mouse click seek to percentage in file corresponding to fraction of width\n"
3661 static int lockmgr(void **mtx, enum AVLockOp op)
3664 case AV_LOCK_CREATE:
3665 *mtx = SDL_CreateMutex();
3669 case AV_LOCK_OBTAIN:
3670 return !!SDL_LockMutex(*mtx);
3671 case AV_LOCK_RELEASE:
3672 return !!SDL_UnlockMutex(*mtx);
3673 case AV_LOCK_DESTROY:
3674 SDL_DestroyMutex(*mtx);
3680 /* Called from the main */
3681 int main(int argc, char **argv)
3685 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3687 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3688 parse_loglevel(argc, argv, options);
3690 /* register all codecs, demux and protocols */
3692 avdevice_register_all();
3695 avfilter_register_all();
3698 avformat_network_init();
3702 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3703 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3705 show_banner(argc, argv, options);
3707 parse_options(NULL, argc, argv, options, opt_input_file);
3709 if (!input_filename) {
3711 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3712 av_log(NULL, AV_LOG_FATAL,
3713 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3717 if (display_disable) {
3720 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3722 flags &= ~SDL_INIT_AUDIO;
3723 if (display_disable)
3724 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3725 #if !defined(_WIN32) && !defined(__APPLE__)
3726 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3728 if (SDL_Init (flags)) {
3729 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3730 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3734 if (!display_disable) {
3735 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3736 fs_screen_width = vi->current_w;
3737 fs_screen_height = vi->current_h;
3740 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3741 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3742 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3744 if (av_lockmgr_register(lockmgr)) {
3745 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3749 av_init_packet(&flush_pkt);
3750 flush_pkt.data = (uint8_t *)&flush_pkt;
3752 is = stream_open(input_filename, file_iformat);
3754 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");