2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 static unsigned sws_flags = SWS_BICUBIC;
110 typedef struct MyAVPacketList {
112 struct MyAVPacketList *next;
116 typedef struct PacketQueue {
117 MyAVPacketList *first_pkt, *last_pkt;
126 #define VIDEO_PICTURE_QUEUE_SIZE 3
127 #define SUBPICTURE_QUEUE_SIZE 16
128 #define SAMPLE_QUEUE_SIZE 9
129 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
131 typedef struct AudioParams {
134 int64_t channel_layout;
135 enum AVSampleFormat fmt;
140 typedef struct Clock {
141 double pts; /* clock base */
142 double pts_drift; /* clock base minus time at which we updated the clock */
145 int serial; /* clock is based on a packet with this serial */
147 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
150 /* Common struct for handling all types of decoded data and allocated render buffers. */
151 typedef struct Frame {
155 double pts; /* presentation timestamp for the frame */
156 double duration; /* estimated duration of the frame */
157 int64_t pos; /* byte position of the frame in the input file */
166 typedef struct FrameQueue {
167 Frame queue[FRAME_QUEUE_SIZE];
180 AV_SYNC_AUDIO_MASTER, /* default choice */
181 AV_SYNC_VIDEO_MASTER,
182 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
185 typedef struct Decoder {
189 AVCodecContext *avctx;
193 SDL_cond *empty_queue_cond;
195 AVRational start_pts_tb;
197 AVRational next_pts_tb;
198 SDL_Thread *decoder_tid;
201 typedef struct VideoState {
202 SDL_Thread *read_tid;
203 AVInputFormat *iformat;
208 int queue_attachments_req;
213 int read_pause_return;
237 int audio_clock_serial;
238 double audio_diff_cum; /* used for AV difference average computation */
239 double audio_diff_avg_coef;
240 double audio_diff_threshold;
241 int audio_diff_avg_count;
244 int audio_hw_buf_size;
245 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
248 unsigned int audio_buf_size; /* in bytes */
249 unsigned int audio_buf1_size;
250 int audio_buf_index; /* in bytes */
251 int audio_write_buf_size;
254 struct AudioParams audio_src;
256 struct AudioParams audio_filter_src;
258 struct AudioParams audio_tgt;
259 struct SwrContext *swr_ctx;
260 int frame_drops_early;
261 int frame_drops_late;
264 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
266 int16_t sample_array[SAMPLE_ARRAY_SIZE];
267 int sample_array_index;
271 FFTSample *rdft_data;
273 double last_vis_time;
276 AVStream *subtitle_st;
277 PacketQueue subtitleq;
280 double frame_last_returned_time;
281 double frame_last_filter_delay;
285 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
287 struct SwsContext *img_convert_ctx;
289 struct SwsContext *sub_convert_ctx;
290 SDL_Rect last_display_rect;
294 int width, height, xleft, ytop;
299 AVFilterContext *in_video_filter; // the first filter in the video chain
300 AVFilterContext *out_video_filter; // the last filter in the video chain
301 AVFilterContext *in_audio_filter; // the first filter in the audio chain
302 AVFilterContext *out_audio_filter; // the last filter in the audio chain
303 AVFilterGraph *agraph; // audio filter graph
306 int last_video_stream, last_audio_stream, last_subtitle_stream;
308 SDL_cond *continue_read_thread;
311 /* options specified by the user */
312 static AVInputFormat *file_iformat;
313 static const char *input_filename;
314 static const char *window_title;
315 static int fs_screen_width;
316 static int fs_screen_height;
317 static int default_width = 640;
318 static int default_height = 480;
319 static int screen_width = 0;
320 static int screen_height = 0;
321 static int audio_disable;
322 static int video_disable;
323 static int subtitle_disable;
324 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
325 static int seek_by_bytes = -1;
326 static int display_disable;
327 static int show_status = 1;
328 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
329 static int64_t start_time = AV_NOPTS_VALUE;
330 static int64_t duration = AV_NOPTS_VALUE;
332 static int genpts = 0;
333 static int lowres = 0;
334 static int decoder_reorder_pts = -1;
336 static int exit_on_keydown;
337 static int exit_on_mousedown;
339 static int framedrop = -1;
340 static int infinite_buffer = -1;
341 static enum ShowMode show_mode = SHOW_MODE_NONE;
342 static const char *audio_codec_name;
343 static const char *subtitle_codec_name;
344 static const char *video_codec_name;
345 double rdftspeed = 0.02;
346 static int64_t cursor_last_shown;
347 static int cursor_hidden = 0;
349 static const char **vfilters_list = NULL;
350 static int nb_vfilters = 0;
351 static char *afilters = NULL;
353 static int autorotate = 1;
355 /* current context */
356 static int is_full_screen;
357 static int64_t audio_callback_time;
359 static AVPacket flush_pkt;
361 #define FF_ALLOC_EVENT (SDL_USEREVENT)
362 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
364 static SDL_Surface *screen;
367 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
369 GROW_ARRAY(vfilters_list, nb_vfilters);
370 vfilters_list[nb_vfilters - 1] = arg;
376 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
377 enum AVSampleFormat fmt2, int64_t channel_count2)
379 /* If channel count == 1, planar and non-planar formats are the same */
380 if (channel_count1 == 1 && channel_count2 == 1)
381 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
383 return channel_count1 != channel_count2 || fmt1 != fmt2;
387 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
389 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
390 return channel_layout;
395 static void free_picture(Frame *vp);
397 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
399 MyAVPacketList *pkt1;
401 if (q->abort_request)
404 pkt1 = av_malloc(sizeof(MyAVPacketList));
409 if (pkt == &flush_pkt)
411 pkt1->serial = q->serial;
416 q->last_pkt->next = pkt1;
419 q->size += pkt1->pkt.size + sizeof(*pkt1);
420 /* XXX: should duplicate packet data in DV case */
421 SDL_CondSignal(q->cond);
425 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
429 /* duplicate the packet */
430 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
433 SDL_LockMutex(q->mutex);
434 ret = packet_queue_put_private(q, pkt);
435 SDL_UnlockMutex(q->mutex);
437 if (pkt != &flush_pkt && ret < 0)
443 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
445 AVPacket pkt1, *pkt = &pkt1;
449 pkt->stream_index = stream_index;
450 return packet_queue_put(q, pkt);
453 /* packet queue handling */
454 static int packet_queue_init(PacketQueue *q)
456 memset(q, 0, sizeof(PacketQueue));
457 q->mutex = SDL_CreateMutex();
459 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
460 return AVERROR(ENOMEM);
462 q->cond = SDL_CreateCond();
464 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
465 return AVERROR(ENOMEM);
467 q->abort_request = 1;
471 static void packet_queue_flush(PacketQueue *q)
473 MyAVPacketList *pkt, *pkt1;
475 SDL_LockMutex(q->mutex);
476 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
478 av_free_packet(&pkt->pkt);
485 SDL_UnlockMutex(q->mutex);
488 static void packet_queue_destroy(PacketQueue *q)
490 packet_queue_flush(q);
491 SDL_DestroyMutex(q->mutex);
492 SDL_DestroyCond(q->cond);
495 static void packet_queue_abort(PacketQueue *q)
497 SDL_LockMutex(q->mutex);
499 q->abort_request = 1;
501 SDL_CondSignal(q->cond);
503 SDL_UnlockMutex(q->mutex);
506 static void packet_queue_start(PacketQueue *q)
508 SDL_LockMutex(q->mutex);
509 q->abort_request = 0;
510 packet_queue_put_private(q, &flush_pkt);
511 SDL_UnlockMutex(q->mutex);
514 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
515 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
517 MyAVPacketList *pkt1;
520 SDL_LockMutex(q->mutex);
523 if (q->abort_request) {
530 q->first_pkt = pkt1->next;
534 q->size -= pkt1->pkt.size + sizeof(*pkt1);
537 *serial = pkt1->serial;
545 SDL_CondWait(q->cond, q->mutex);
548 SDL_UnlockMutex(q->mutex);
552 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
553 memset(d, 0, sizeof(Decoder));
556 d->empty_queue_cond = empty_queue_cond;
557 d->start_pts = AV_NOPTS_VALUE;
560 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
566 if (d->queue->abort_request)
569 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
572 if (d->queue->nb_packets == 0)
573 SDL_CondSignal(d->empty_queue_cond);
574 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
576 if (pkt.data == flush_pkt.data) {
577 avcodec_flush_buffers(d->avctx);
579 d->next_pts = d->start_pts;
580 d->next_pts_tb = d->start_pts_tb;
582 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
583 av_free_packet(&d->pkt);
584 d->pkt_temp = d->pkt = pkt;
585 d->packet_pending = 1;
588 switch (d->avctx->codec_type) {
589 case AVMEDIA_TYPE_VIDEO:
590 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
592 if (decoder_reorder_pts == -1) {
593 frame->pts = av_frame_get_best_effort_timestamp(frame);
594 } else if (decoder_reorder_pts) {
595 frame->pts = frame->pkt_pts;
597 frame->pts = frame->pkt_dts;
601 case AVMEDIA_TYPE_AUDIO:
602 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
604 AVRational tb = (AVRational){1, frame->sample_rate};
605 if (frame->pts != AV_NOPTS_VALUE)
606 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
607 else if (frame->pkt_pts != AV_NOPTS_VALUE)
608 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
609 else if (d->next_pts != AV_NOPTS_VALUE)
610 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
611 if (frame->pts != AV_NOPTS_VALUE) {
612 d->next_pts = frame->pts + frame->nb_samples;
617 case AVMEDIA_TYPE_SUBTITLE:
618 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
623 d->packet_pending = 0;
626 d->pkt_temp.pts = AV_NOPTS_VALUE;
627 if (d->pkt_temp.data) {
628 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
629 ret = d->pkt_temp.size;
630 d->pkt_temp.data += ret;
631 d->pkt_temp.size -= ret;
632 if (d->pkt_temp.size <= 0)
633 d->packet_pending = 0;
636 d->packet_pending = 0;
637 d->finished = d->pkt_serial;
641 } while (!got_frame && !d->finished);
646 static void decoder_destroy(Decoder *d) {
647 av_free_packet(&d->pkt);
650 static void frame_queue_unref_item(Frame *vp)
652 av_frame_unref(vp->frame);
653 avsubtitle_free(&vp->sub);
656 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
659 memset(f, 0, sizeof(FrameQueue));
660 if (!(f->mutex = SDL_CreateMutex())) {
661 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
662 return AVERROR(ENOMEM);
664 if (!(f->cond = SDL_CreateCond())) {
665 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
666 return AVERROR(ENOMEM);
669 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
670 f->keep_last = !!keep_last;
671 for (i = 0; i < f->max_size; i++)
672 if (!(f->queue[i].frame = av_frame_alloc()))
673 return AVERROR(ENOMEM);
677 static void frame_queue_destory(FrameQueue *f)
680 for (i = 0; i < f->max_size; i++) {
681 Frame *vp = &f->queue[i];
682 frame_queue_unref_item(vp);
683 av_frame_free(&vp->frame);
686 SDL_DestroyMutex(f->mutex);
687 SDL_DestroyCond(f->cond);
690 static void frame_queue_signal(FrameQueue *f)
692 SDL_LockMutex(f->mutex);
693 SDL_CondSignal(f->cond);
694 SDL_UnlockMutex(f->mutex);
697 static Frame *frame_queue_peek(FrameQueue *f)
699 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
702 static Frame *frame_queue_peek_next(FrameQueue *f)
704 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
707 static Frame *frame_queue_peek_last(FrameQueue *f)
709 return &f->queue[f->rindex];
712 static Frame *frame_queue_peek_writable(FrameQueue *f)
714 /* wait until we have space to put a new frame */
715 SDL_LockMutex(f->mutex);
716 while (f->size >= f->max_size &&
717 !f->pktq->abort_request) {
718 SDL_CondWait(f->cond, f->mutex);
720 SDL_UnlockMutex(f->mutex);
722 if (f->pktq->abort_request)
725 return &f->queue[f->windex];
728 static Frame *frame_queue_peek_readable(FrameQueue *f)
730 /* wait until we have a readable a new frame */
731 SDL_LockMutex(f->mutex);
732 while (f->size - f->rindex_shown <= 0 &&
733 !f->pktq->abort_request) {
734 SDL_CondWait(f->cond, f->mutex);
736 SDL_UnlockMutex(f->mutex);
738 if (f->pktq->abort_request)
741 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
744 static void frame_queue_push(FrameQueue *f)
746 if (++f->windex == f->max_size)
748 SDL_LockMutex(f->mutex);
750 SDL_CondSignal(f->cond);
751 SDL_UnlockMutex(f->mutex);
754 static void frame_queue_next(FrameQueue *f)
756 if (f->keep_last && !f->rindex_shown) {
760 frame_queue_unref_item(&f->queue[f->rindex]);
761 if (++f->rindex == f->max_size)
763 SDL_LockMutex(f->mutex);
765 SDL_CondSignal(f->cond);
766 SDL_UnlockMutex(f->mutex);
769 /* jump back to the previous frame if available by resetting rindex_shown */
770 static int frame_queue_prev(FrameQueue *f)
772 int ret = f->rindex_shown;
777 /* return the number of undisplayed frames in the queue */
778 static int frame_queue_nb_remaining(FrameQueue *f)
780 return f->size - f->rindex_shown;
783 /* return last shown position */
784 static int64_t frame_queue_last_pos(FrameQueue *f)
786 Frame *fp = &f->queue[f->rindex];
787 if (f->rindex_shown && fp->serial == f->pktq->serial)
793 static void decoder_abort(Decoder *d, FrameQueue *fq)
795 packet_queue_abort(d->queue);
796 frame_queue_signal(fq);
797 SDL_WaitThread(d->decoder_tid, NULL);
798 d->decoder_tid = NULL;
799 packet_queue_flush(d->queue);
802 static inline void fill_rectangle(SDL_Surface *screen,
803 int x, int y, int w, int h, int color, int update)
810 SDL_FillRect(screen, &rect, color);
811 if (update && w > 0 && h > 0)
812 SDL_UpdateRect(screen, x, y, w, h);
815 /* draw only the border of a rectangle */
816 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
820 /* fill the background */
824 w2 = width - (x + w);
830 h2 = height - (y + h);
833 fill_rectangle(screen,
837 fill_rectangle(screen,
838 xleft + width - w2, ytop,
841 fill_rectangle(screen,
845 fill_rectangle(screen,
846 xleft + w1, ytop + height - h2,
851 #define ALPHA_BLEND(a, oldp, newp, s)\
852 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
858 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
860 int x, y, Y, U, V, A;
861 uint8_t *lum, *cb, *cr;
862 int dstx, dsty, dstw, dsth;
863 const AVPicture *src = &rect->pict;
865 dstw = av_clip(rect->w, 0, imgw);
866 dsth = av_clip(rect->h, 0, imgh);
867 dstx = av_clip(rect->x, 0, imgw - dstw);
868 dsty = av_clip(rect->y, 0, imgh - dsth);
869 lum = dst->data[0] + dstx + dsty * dst->linesize[0];
870 cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
871 cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
873 for (y = 0; y<dsth; y++) {
874 for (x = 0; x<dstw; x++) {
875 Y = src->data[0][x + y*src->linesize[0]];
876 A = src->data[3][x + y*src->linesize[3]];
877 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
880 lum += dst->linesize[0] - dstw;
883 for (y = 0; y<dsth/2; y++) {
884 for (x = 0; x<dstw/2; x++) {
885 U = src->data[1][x + y*src->linesize[1]];
886 V = src->data[2][x + y*src->linesize[2]];
887 A = src->data[3][2*x + 2*y *src->linesize[3]]
888 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
889 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
890 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
891 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
892 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
896 cb += dst->linesize[1] - dstw/2;
897 cr += dst->linesize[2] - dstw/2;
901 static void free_picture(Frame *vp)
904 SDL_FreeYUVOverlay(vp->bmp);
909 static void calculate_display_rect(SDL_Rect *rect,
910 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
911 int pic_width, int pic_height, AVRational pic_sar)
914 int width, height, x, y;
916 if (pic_sar.num == 0)
919 aspect_ratio = av_q2d(pic_sar);
921 if (aspect_ratio <= 0.0)
923 aspect_ratio *= (float)pic_width / (float)pic_height;
925 /* XXX: we suppose the screen has a 1.0 pixel ratio */
927 width = ((int)rint(height * aspect_ratio)) & ~1;
928 if (width > scr_width) {
930 height = ((int)rint(width / aspect_ratio)) & ~1;
932 x = (scr_width - width) / 2;
933 y = (scr_height - height) / 2;
934 rect->x = scr_xleft + x;
935 rect->y = scr_ytop + y;
936 rect->w = FFMAX(width, 1);
937 rect->h = FFMAX(height, 1);
940 static void video_image_display(VideoState *is)
948 vp = frame_queue_peek(&is->pictq);
950 if (is->subtitle_st) {
951 if (frame_queue_nb_remaining(&is->subpq) > 0) {
952 sp = frame_queue_peek(&is->subpq);
954 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
955 SDL_LockYUVOverlay (vp->bmp);
957 pict.data[0] = vp->bmp->pixels[0];
958 pict.data[1] = vp->bmp->pixels[2];
959 pict.data[2] = vp->bmp->pixels[1];
961 pict.linesize[0] = vp->bmp->pitches[0];
962 pict.linesize[1] = vp->bmp->pitches[2];
963 pict.linesize[2] = vp->bmp->pitches[1];
965 for (i = 0; i < sp->sub.num_rects; i++)
966 blend_subrect(&pict, sp->sub.rects[i],
967 vp->bmp->w, vp->bmp->h);
969 SDL_UnlockYUVOverlay (vp->bmp);
974 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
976 SDL_DisplayYUVOverlay(vp->bmp, &rect);
978 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) {
979 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
980 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
981 is->last_display_rect = rect;
986 static inline int compute_mod(int a, int b)
988 return a < 0 ? a%b + b : a%b;
991 static void video_audio_display(VideoState *s)
993 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
994 int ch, channels, h, h2, bgcolor, fgcolor;
996 int rdft_bits, nb_freq;
998 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1000 nb_freq = 1 << (rdft_bits - 1);
1002 /* compute display index : center on currently output samples */
1003 channels = s->audio_tgt.channels;
1004 nb_display_channels = channels;
1006 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1008 delay = s->audio_write_buf_size;
1011 /* to be more precise, we take into account the time spent since
1012 the last buffer computation */
1013 if (audio_callback_time) {
1014 time_diff = av_gettime_relative() - audio_callback_time;
1015 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1018 delay += 2 * data_used;
1019 if (delay < data_used)
1022 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1023 if (s->show_mode == SHOW_MODE_WAVES) {
1025 for (i = 0; i < 1000; i += channels) {
1026 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1027 int a = s->sample_array[idx];
1028 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1029 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1030 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1032 if (h < score && (b ^ c) < 0) {
1039 s->last_i_start = i_start;
1041 i_start = s->last_i_start;
1044 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1045 if (s->show_mode == SHOW_MODE_WAVES) {
1046 fill_rectangle(screen,
1047 s->xleft, s->ytop, s->width, s->height,
1050 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1052 /* total height for one channel */
1053 h = s->height / nb_display_channels;
1054 /* graph height / 2 */
1056 for (ch = 0; ch < nb_display_channels; ch++) {
1058 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1059 for (x = 0; x < s->width; x++) {
1060 y = (s->sample_array[i] * h2) >> 15;
1067 fill_rectangle(screen,
1068 s->xleft + x, ys, 1, y,
1071 if (i >= SAMPLE_ARRAY_SIZE)
1072 i -= SAMPLE_ARRAY_SIZE;
1076 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1078 for (ch = 1; ch < nb_display_channels; ch++) {
1079 y = s->ytop + ch * h;
1080 fill_rectangle(screen,
1081 s->xleft, y, s->width, 1,
1084 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1086 nb_display_channels= FFMIN(nb_display_channels, 2);
1087 if (rdft_bits != s->rdft_bits) {
1088 av_rdft_end(s->rdft);
1089 av_free(s->rdft_data);
1090 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1091 s->rdft_bits = rdft_bits;
1092 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1094 if (!s->rdft || !s->rdft_data){
1095 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1096 s->show_mode = SHOW_MODE_WAVES;
1099 for (ch = 0; ch < nb_display_channels; ch++) {
1100 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1102 for (x = 0; x < 2 * nb_freq; x++) {
1103 double w = (x-nb_freq) * (1.0 / nb_freq);
1104 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1106 if (i >= SAMPLE_ARRAY_SIZE)
1107 i -= SAMPLE_ARRAY_SIZE;
1109 av_rdft_calc(s->rdft, data[ch]);
1111 /* Least efficient way to do this, we should of course
1112 * directly access it but it is more than fast enough. */
1113 for (y = 0; y < s->height; y++) {
1114 double w = 1 / sqrt(nb_freq);
1115 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]));
1116 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1117 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1120 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1122 fill_rectangle(screen,
1123 s->xpos, s->height-y, 1, 1,
1127 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1130 if (s->xpos >= s->width)
1135 static void stream_component_close(VideoState *is, int stream_index)
1137 AVFormatContext *ic = is->ic;
1138 AVCodecContext *avctx;
1140 if (stream_index < 0 || stream_index >= ic->nb_streams)
1142 avctx = ic->streams[stream_index]->codec;
1144 switch (avctx->codec_type) {
1145 case AVMEDIA_TYPE_AUDIO:
1146 decoder_abort(&is->auddec, &is->sampq);
1148 decoder_destroy(&is->auddec);
1149 swr_free(&is->swr_ctx);
1150 av_freep(&is->audio_buf1);
1151 is->audio_buf1_size = 0;
1152 is->audio_buf = NULL;
1155 av_rdft_end(is->rdft);
1156 av_freep(&is->rdft_data);
1161 case AVMEDIA_TYPE_VIDEO:
1162 decoder_abort(&is->viddec, &is->pictq);
1163 decoder_destroy(&is->viddec);
1165 case AVMEDIA_TYPE_SUBTITLE:
1166 decoder_abort(&is->subdec, &is->subpq);
1167 decoder_destroy(&is->subdec);
1173 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1174 avcodec_close(avctx);
1175 switch (avctx->codec_type) {
1176 case AVMEDIA_TYPE_AUDIO:
1177 is->audio_st = NULL;
1178 is->audio_stream = -1;
1180 case AVMEDIA_TYPE_VIDEO:
1181 is->video_st = NULL;
1182 is->video_stream = -1;
1184 case AVMEDIA_TYPE_SUBTITLE:
1185 is->subtitle_st = NULL;
1186 is->subtitle_stream = -1;
1193 static void stream_close(VideoState *is)
1195 /* XXX: use a special url_shutdown call to abort parse cleanly */
1196 is->abort_request = 1;
1197 SDL_WaitThread(is->read_tid, NULL);
1199 /* close each stream */
1200 if (is->audio_stream >= 0)
1201 stream_component_close(is, is->audio_stream);
1202 if (is->video_stream >= 0)
1203 stream_component_close(is, is->video_stream);
1204 if (is->subtitle_stream >= 0)
1205 stream_component_close(is, is->subtitle_stream);
1207 avformat_close_input(&is->ic);
1209 packet_queue_destroy(&is->videoq);
1210 packet_queue_destroy(&is->audioq);
1211 packet_queue_destroy(&is->subtitleq);
1213 /* free all pictures */
1214 frame_queue_destory(&is->pictq);
1215 frame_queue_destory(&is->sampq);
1216 frame_queue_destory(&is->subpq);
1217 SDL_DestroyCond(is->continue_read_thread);
1218 #if !CONFIG_AVFILTER
1219 sws_freeContext(is->img_convert_ctx);
1221 sws_freeContext(is->sub_convert_ctx);
1222 av_free(is->filename);
1226 static void do_exit(VideoState *is)
1231 av_lockmgr_register(NULL);
1234 av_freep(&vfilters_list);
1236 avformat_network_deinit();
1240 av_log(NULL, AV_LOG_QUIET, "%s", "");
1244 static void sigterm_handler(int sig)
1249 static void set_default_window_size(int width, int height, AVRational sar)
1252 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1253 default_width = rect.w;
1254 default_height = rect.h;
1257 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1259 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1262 if (is_full_screen) flags |= SDL_FULLSCREEN;
1263 else flags |= SDL_RESIZABLE;
1265 if (vp && vp->width)
1266 set_default_window_size(vp->width, vp->height, vp->sar);
1268 if (is_full_screen && fs_screen_width) {
1269 w = fs_screen_width;
1270 h = fs_screen_height;
1271 } else if (!is_full_screen && screen_width) {
1278 w = FFMIN(16383, w);
1279 if (screen && is->width == screen->w && screen->w == w
1280 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1282 screen = SDL_SetVideoMode(w, h, 0, flags);
1284 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1288 window_title = input_filename;
1289 SDL_WM_SetCaption(window_title, window_title);
1291 is->width = screen->w;
1292 is->height = screen->h;
1297 /* display the current picture, if any */
1298 static void video_display(VideoState *is)
1301 video_open(is, 0, NULL);
1302 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1303 video_audio_display(is);
1304 else if (is->video_st)
1305 video_image_display(is);
1308 static double get_clock(Clock *c)
1310 if (*c->queue_serial != c->serial)
1315 double time = av_gettime_relative() / 1000000.0;
1316 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1320 static void set_clock_at(Clock *c, double pts, int serial, double time)
1323 c->last_updated = time;
1324 c->pts_drift = c->pts - time;
1328 static void set_clock(Clock *c, double pts, int serial)
1330 double time = av_gettime_relative() / 1000000.0;
1331 set_clock_at(c, pts, serial, time);
1334 static void set_clock_speed(Clock *c, double speed)
1336 set_clock(c, get_clock(c), c->serial);
1340 static void init_clock(Clock *c, int *queue_serial)
1344 c->queue_serial = queue_serial;
1345 set_clock(c, NAN, -1);
1348 static void sync_clock_to_slave(Clock *c, Clock *slave)
1350 double clock = get_clock(c);
1351 double slave_clock = get_clock(slave);
1352 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1353 set_clock(c, slave_clock, slave->serial);
1356 static int get_master_sync_type(VideoState *is) {
1357 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1359 return AV_SYNC_VIDEO_MASTER;
1361 return AV_SYNC_AUDIO_MASTER;
1362 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1364 return AV_SYNC_AUDIO_MASTER;
1366 return AV_SYNC_EXTERNAL_CLOCK;
1368 return AV_SYNC_EXTERNAL_CLOCK;
1372 /* get the current master clock value */
1373 static double get_master_clock(VideoState *is)
1377 switch (get_master_sync_type(is)) {
1378 case AV_SYNC_VIDEO_MASTER:
1379 val = get_clock(&is->vidclk);
1381 case AV_SYNC_AUDIO_MASTER:
1382 val = get_clock(&is->audclk);
1385 val = get_clock(&is->extclk);
1391 static void check_external_clock_speed(VideoState *is) {
1392 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1393 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1394 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1395 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1396 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1397 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1399 double speed = is->extclk.speed;
1401 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1405 /* seek in the stream */
1406 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1408 if (!is->seek_req) {
1411 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1413 is->seek_flags |= AVSEEK_FLAG_BYTE;
1415 SDL_CondSignal(is->continue_read_thread);
1419 /* pause or resume the video */
1420 static void stream_toggle_pause(VideoState *is)
1423 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1424 if (is->read_pause_return != AVERROR(ENOSYS)) {
1425 is->vidclk.paused = 0;
1427 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1429 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1430 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1433 static void toggle_pause(VideoState *is)
1435 stream_toggle_pause(is);
1439 static void toggle_mute(VideoState *is)
1441 is->muted = !is->muted;
1444 static void update_volume(VideoState *is, int sign, int step)
1446 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1449 static void step_to_next_frame(VideoState *is)
1451 /* if the stream is paused unpause it, then step */
1453 stream_toggle_pause(is);
1457 static double compute_target_delay(double delay, VideoState *is)
1459 double sync_threshold, diff = 0;
1461 /* update delay to follow master synchronisation source */
1462 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1463 /* if video is slave, we try to correct big delays by
1464 duplicating or deleting a frame */
1465 diff = get_clock(&is->vidclk) - get_master_clock(is);
1467 /* skip or repeat frame. We take into account the
1468 delay to compute the threshold. I still don't know
1469 if it is the best guess */
1470 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1471 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1472 if (diff <= -sync_threshold)
1473 delay = FFMAX(0, delay + diff);
1474 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1475 delay = delay + diff;
1476 else if (diff >= sync_threshold)
1481 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1487 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1488 if (vp->serial == nextvp->serial) {
1489 double duration = nextvp->pts - vp->pts;
1490 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1491 return vp->duration;
1499 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1500 /* update current video pts */
1501 set_clock(&is->vidclk, pts, serial);
1502 sync_clock_to_slave(&is->extclk, &is->vidclk);
1505 /* called to display each frame */
1506 static void video_refresh(void *opaque, double *remaining_time)
1508 VideoState *is = opaque;
1513 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1514 check_external_clock_speed(is);
1516 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1517 time = av_gettime_relative() / 1000000.0;
1518 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1520 is->last_vis_time = time;
1522 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1527 if (is->force_refresh)
1528 redisplay = frame_queue_prev(&is->pictq);
1530 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1531 // nothing to do, no picture to display in the queue
1533 double last_duration, duration, delay;
1536 /* dequeue the picture */
1537 lastvp = frame_queue_peek_last(&is->pictq);
1538 vp = frame_queue_peek(&is->pictq);
1540 if (vp->serial != is->videoq.serial) {
1541 frame_queue_next(&is->pictq);
1546 if (lastvp->serial != vp->serial && !redisplay)
1547 is->frame_timer = av_gettime_relative() / 1000000.0;
1552 /* compute nominal last_duration */
1553 last_duration = vp_duration(is, lastvp, vp);
1557 delay = compute_target_delay(last_duration, is);
1559 time= av_gettime_relative()/1000000.0;
1560 if (time < is->frame_timer + delay && !redisplay) {
1561 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1565 is->frame_timer += delay;
1566 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1567 is->frame_timer = time;
1569 SDL_LockMutex(is->pictq.mutex);
1570 if (!redisplay && !isnan(vp->pts))
1571 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1572 SDL_UnlockMutex(is->pictq.mutex);
1574 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1575 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1576 duration = vp_duration(is, vp, nextvp);
1577 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1579 is->frame_drops_late++;
1580 frame_queue_next(&is->pictq);
1586 if (is->subtitle_st) {
1587 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1588 sp = frame_queue_peek(&is->subpq);
1590 if (frame_queue_nb_remaining(&is->subpq) > 1)
1591 sp2 = frame_queue_peek_next(&is->subpq);
1595 if (sp->serial != is->subtitleq.serial
1596 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1597 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1599 frame_queue_next(&is->subpq);
1607 /* display picture */
1608 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1611 frame_queue_next(&is->pictq);
1613 if (is->step && !is->paused)
1614 stream_toggle_pause(is);
1617 is->force_refresh = 0;
1619 static int64_t last_time;
1621 int aqsize, vqsize, sqsize;
1624 cur_time = av_gettime_relative();
1625 if (!last_time || (cur_time - last_time) >= 30000) {
1630 aqsize = is->audioq.size;
1632 vqsize = is->videoq.size;
1633 if (is->subtitle_st)
1634 sqsize = is->subtitleq.size;
1636 if (is->audio_st && is->video_st)
1637 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1638 else if (is->video_st)
1639 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1640 else if (is->audio_st)
1641 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1642 av_log(NULL, AV_LOG_INFO,
1643 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1644 get_master_clock(is),
1645 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1647 is->frame_drops_early + is->frame_drops_late,
1651 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1652 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1654 last_time = cur_time;
1659 /* allocate a picture (needs to do that in main thread to avoid
1660 potential locking problems */
1661 static void alloc_picture(VideoState *is)
1666 vp = &is->pictq.queue[is->pictq.windex];
1670 video_open(is, 0, vp);
1672 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1675 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1676 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1677 /* SDL allocates a buffer smaller than requested if the video
1678 * overlay hardware is unable to support the requested size. */
1679 av_log(NULL, AV_LOG_FATAL,
1680 "Error: the video system does not support an image\n"
1681 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1682 "to reduce the image size.\n", vp->width, vp->height );
1686 SDL_LockMutex(is->pictq.mutex);
1688 SDL_CondSignal(is->pictq.cond);
1689 SDL_UnlockMutex(is->pictq.mutex);
1692 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1693 int i, width, height;
1695 for (i = 0; i < 3; i++) {
1702 if (bmp->pitches[i] > width) {
1703 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1704 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1710 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1714 #if defined(DEBUG_SYNC) && 0
1715 printf("frame_type=%c pts=%0.3f\n",
1716 av_get_picture_type_char(src_frame->pict_type), pts);
1719 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1722 vp->sar = src_frame->sample_aspect_ratio;
1724 /* alloc or resize hardware picture buffer */
1725 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1726 vp->width != src_frame->width ||
1727 vp->height != src_frame->height) {
1732 vp->width = src_frame->width;
1733 vp->height = src_frame->height;
1735 /* the allocation must be done in the main thread to avoid
1736 locking problems. */
1737 event.type = FF_ALLOC_EVENT;
1738 event.user.data1 = is;
1739 SDL_PushEvent(&event);
1741 /* wait until the picture is allocated */
1742 SDL_LockMutex(is->pictq.mutex);
1743 while (!vp->allocated && !is->videoq.abort_request) {
1744 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1746 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1747 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1748 while (!vp->allocated && !is->abort_request) {
1749 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1752 SDL_UnlockMutex(is->pictq.mutex);
1754 if (is->videoq.abort_request)
1758 /* if the frame is not skipped, then display it */
1760 AVPicture pict = { { 0 } };
1762 /* get a pointer on the bitmap */
1763 SDL_LockYUVOverlay (vp->bmp);
1765 pict.data[0] = vp->bmp->pixels[0];
1766 pict.data[1] = vp->bmp->pixels[2];
1767 pict.data[2] = vp->bmp->pixels[1];
1769 pict.linesize[0] = vp->bmp->pitches[0];
1770 pict.linesize[1] = vp->bmp->pitches[2];
1771 pict.linesize[2] = vp->bmp->pitches[1];
1774 // FIXME use direct rendering
1775 av_picture_copy(&pict, (AVPicture *)src_frame,
1776 src_frame->format, vp->width, vp->height);
1779 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1781 const AVClass *class = sws_get_class();
1782 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1783 AV_OPT_SEARCH_FAKE_OBJ);
1784 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1790 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1791 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1792 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1793 if (!is->img_convert_ctx) {
1794 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1797 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1798 0, vp->height, pict.data, pict.linesize);
1800 /* workaround SDL PITCH_WORKAROUND */
1801 duplicate_right_border_pixels(vp->bmp);
1802 /* update the bitmap content */
1803 SDL_UnlockYUVOverlay(vp->bmp);
1806 vp->duration = duration;
1808 vp->serial = serial;
1810 /* now we can update the picture count */
1811 frame_queue_push(&is->pictq);
1816 static int get_video_frame(VideoState *is, AVFrame *frame)
1820 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1826 if (frame->pts != AV_NOPTS_VALUE)
1827 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1829 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1831 is->viddec_width = frame->width;
1832 is->viddec_height = frame->height;
1834 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1835 if (frame->pts != AV_NOPTS_VALUE) {
1836 double diff = dpts - get_master_clock(is);
1837 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1838 diff - is->frame_last_filter_delay < 0 &&
1839 is->viddec.pkt_serial == is->vidclk.serial &&
1840 is->videoq.nb_packets) {
1841 is->frame_drops_early++;
1842 av_frame_unref(frame);
1853 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1854 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1857 int nb_filters = graph->nb_filters;
1858 AVFilterInOut *outputs = NULL, *inputs = NULL;
1861 outputs = avfilter_inout_alloc();
1862 inputs = avfilter_inout_alloc();
1863 if (!outputs || !inputs) {
1864 ret = AVERROR(ENOMEM);
1868 outputs->name = av_strdup("in");
1869 outputs->filter_ctx = source_ctx;
1870 outputs->pad_idx = 0;
1871 outputs->next = NULL;
1873 inputs->name = av_strdup("out");
1874 inputs->filter_ctx = sink_ctx;
1875 inputs->pad_idx = 0;
1876 inputs->next = NULL;
1878 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1881 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1885 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1886 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1887 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1889 ret = avfilter_graph_config(graph, NULL);
1891 avfilter_inout_free(&outputs);
1892 avfilter_inout_free(&inputs);
1896 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1898 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1899 char sws_flags_str[512] = "";
1900 char buffersrc_args[256];
1902 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1903 AVCodecContext *codec = is->video_st->codec;
1904 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1905 AVDictionaryEntry *e = NULL;
1907 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1908 if (!strcmp(e->key, "sws_flags")) {
1909 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1911 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1913 if (strlen(sws_flags_str))
1914 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1916 graph->scale_sws_opts = av_strdup(sws_flags_str);
1918 snprintf(buffersrc_args, sizeof(buffersrc_args),
1919 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1920 frame->width, frame->height, frame->format,
1921 is->video_st->time_base.num, is->video_st->time_base.den,
1922 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1923 if (fr.num && fr.den)
1924 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1926 if ((ret = avfilter_graph_create_filter(&filt_src,
1927 avfilter_get_by_name("buffer"),
1928 "ffplay_buffer", buffersrc_args, NULL,
1932 ret = avfilter_graph_create_filter(&filt_out,
1933 avfilter_get_by_name("buffersink"),
1934 "ffplay_buffersink", NULL, NULL, graph);
1938 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1941 last_filter = filt_out;
1943 /* Note: this macro adds a filter before the lastly added filter, so the
1944 * processing order of the filters is in reverse */
1945 #define INSERT_FILT(name, arg) do { \
1946 AVFilterContext *filt_ctx; \
1948 ret = avfilter_graph_create_filter(&filt_ctx, \
1949 avfilter_get_by_name(name), \
1950 "ffplay_" name, arg, NULL, graph); \
1954 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1958 last_filter = filt_ctx; \
1961 /* SDL YUV code is not handling odd width/height for some driver
1962 * combinations, therefore we crop the picture to an even width/height. */
1963 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1966 double theta = get_rotation(is->video_st);
1968 if (fabs(theta - 90) < 1.0) {
1969 INSERT_FILT("transpose", "clock");
1970 } else if (fabs(theta - 180) < 1.0) {
1971 INSERT_FILT("hflip", NULL);
1972 INSERT_FILT("vflip", NULL);
1973 } else if (fabs(theta - 270) < 1.0) {
1974 INSERT_FILT("transpose", "cclock");
1975 } else if (fabs(theta) > 1.0) {
1976 char rotate_buf[64];
1977 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1978 INSERT_FILT("rotate", rotate_buf);
1982 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1985 is->in_video_filter = filt_src;
1986 is->out_video_filter = filt_out;
1992 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1994 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1995 int sample_rates[2] = { 0, -1 };
1996 int64_t channel_layouts[2] = { 0, -1 };
1997 int channels[2] = { 0, -1 };
1998 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1999 char aresample_swr_opts[512] = "";
2000 AVDictionaryEntry *e = NULL;
2001 char asrc_args[256];
2004 avfilter_graph_free(&is->agraph);
2005 if (!(is->agraph = avfilter_graph_alloc()))
2006 return AVERROR(ENOMEM);
2008 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2009 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2010 if (strlen(aresample_swr_opts))
2011 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2012 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2014 ret = snprintf(asrc_args, sizeof(asrc_args),
2015 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2016 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2017 is->audio_filter_src.channels,
2018 1, is->audio_filter_src.freq);
2019 if (is->audio_filter_src.channel_layout)
2020 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2021 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2023 ret = avfilter_graph_create_filter(&filt_asrc,
2024 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2025 asrc_args, NULL, is->agraph);
2030 ret = avfilter_graph_create_filter(&filt_asink,
2031 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2032 NULL, NULL, is->agraph);
2036 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2038 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2041 if (force_output_format) {
2042 channel_layouts[0] = is->audio_tgt.channel_layout;
2043 channels [0] = is->audio_tgt.channels;
2044 sample_rates [0] = is->audio_tgt.freq;
2045 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2047 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2049 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2051 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2056 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2059 is->in_audio_filter = filt_asrc;
2060 is->out_audio_filter = filt_asink;
2064 avfilter_graph_free(&is->agraph);
2067 #endif /* CONFIG_AVFILTER */
2069 static int audio_thread(void *arg)
2071 VideoState *is = arg;
2072 AVFrame *frame = av_frame_alloc();
2075 int last_serial = -1;
2076 int64_t dec_channel_layout;
2084 return AVERROR(ENOMEM);
2087 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2091 tb = (AVRational){1, frame->sample_rate};
2094 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2097 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2098 frame->format, av_frame_get_channels(frame)) ||
2099 is->audio_filter_src.channel_layout != dec_channel_layout ||
2100 is->audio_filter_src.freq != frame->sample_rate ||
2101 is->auddec.pkt_serial != last_serial;
2104 char buf1[1024], buf2[1024];
2105 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2106 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2107 av_log(NULL, AV_LOG_DEBUG,
2108 "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",
2109 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2110 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2112 is->audio_filter_src.fmt = frame->format;
2113 is->audio_filter_src.channels = av_frame_get_channels(frame);
2114 is->audio_filter_src.channel_layout = dec_channel_layout;
2115 is->audio_filter_src.freq = frame->sample_rate;
2116 last_serial = is->auddec.pkt_serial;
2118 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2122 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2125 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2126 tb = is->out_audio_filter->inputs[0]->time_base;
2128 if (!(af = frame_queue_peek_writable(&is->sampq)))
2131 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2132 af->pos = av_frame_get_pkt_pos(frame);
2133 af->serial = is->auddec.pkt_serial;
2134 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2136 av_frame_move_ref(af->frame, frame);
2137 frame_queue_push(&is->sampq);
2140 if (is->audioq.serial != is->auddec.pkt_serial)
2143 if (ret == AVERROR_EOF)
2144 is->auddec.finished = is->auddec.pkt_serial;
2147 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2150 avfilter_graph_free(&is->agraph);
2152 av_frame_free(&frame);
2156 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2158 packet_queue_start(d->queue);
2159 d->decoder_tid = SDL_CreateThread(fn, arg);
2160 if (!d->decoder_tid) {
2161 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2162 return AVERROR(ENOMEM);
2167 static int video_thread(void *arg)
2169 VideoState *is = arg;
2170 AVFrame *frame = av_frame_alloc();
2174 AVRational tb = is->video_st->time_base;
2175 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2178 AVFilterGraph *graph = avfilter_graph_alloc();
2179 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2182 enum AVPixelFormat last_format = -2;
2183 int last_serial = -1;
2184 int last_vfilter_idx = 0;
2186 av_frame_free(&frame);
2187 return AVERROR(ENOMEM);
2194 avfilter_graph_free(&graph);
2196 return AVERROR(ENOMEM);
2200 ret = get_video_frame(is, frame);
2207 if ( last_w != frame->width
2208 || last_h != frame->height
2209 || last_format != frame->format
2210 || last_serial != is->viddec.pkt_serial
2211 || last_vfilter_idx != is->vfilter_idx) {
2212 av_log(NULL, AV_LOG_DEBUG,
2213 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2215 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2216 frame->width, frame->height,
2217 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2218 avfilter_graph_free(&graph);
2219 graph = avfilter_graph_alloc();
2220 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2222 event.type = FF_QUIT_EVENT;
2223 event.user.data1 = is;
2224 SDL_PushEvent(&event);
2227 filt_in = is->in_video_filter;
2228 filt_out = is->out_video_filter;
2229 last_w = frame->width;
2230 last_h = frame->height;
2231 last_format = frame->format;
2232 last_serial = is->viddec.pkt_serial;
2233 last_vfilter_idx = is->vfilter_idx;
2234 frame_rate = filt_out->inputs[0]->frame_rate;
2237 ret = av_buffersrc_add_frame(filt_in, frame);
2242 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2244 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2246 if (ret == AVERROR_EOF)
2247 is->viddec.finished = is->viddec.pkt_serial;
2252 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2253 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2254 is->frame_last_filter_delay = 0;
2255 tb = filt_out->inputs[0]->time_base;
2257 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2258 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2259 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2260 av_frame_unref(frame);
2270 avfilter_graph_free(&graph);
2272 av_frame_free(&frame);
2276 static int subtitle_thread(void *arg)
2278 VideoState *is = arg;
2285 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2288 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2293 if (got_subtitle && sp->sub.format == 0) {
2294 if (sp->sub.pts != AV_NOPTS_VALUE)
2295 pts = sp->sub.pts / (double)AV_TIME_BASE;
2297 sp->serial = is->subdec.pkt_serial;
2299 for (i = 0; i < sp->sub.num_rects; i++)
2301 int in_w = sp->sub.rects[i]->w;
2302 int in_h = sp->sub.rects[i]->h;
2303 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2304 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2305 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2306 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2309 //can not use avpicture_alloc as it is not compatible with avsubtitle_free()
2310 av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);
2311 newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
2312 newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
2313 newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
2314 newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
2316 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2317 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2318 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2319 if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||
2320 !newpic.data[1] || !newpic.data[2]
2322 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2325 sws_scale(is->sub_convert_ctx,
2326 (void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,
2327 0, in_h, newpic.data, newpic.linesize);
2329 av_free(sp->sub.rects[i]->pict.data[0]);
2330 av_free(sp->sub.rects[i]->pict.data[1]);
2331 sp->sub.rects[i]->pict = newpic;
2332 sp->sub.rects[i]->w = out_w;
2333 sp->sub.rects[i]->h = out_h;
2334 sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2335 sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2338 /* now we can update the picture count */
2339 frame_queue_push(&is->subpq);
2340 } else if (got_subtitle) {
2341 avsubtitle_free(&sp->sub);
2347 /* copy samples for viewing in editor window */
2348 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2352 size = samples_size / sizeof(short);
2354 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2357 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2359 is->sample_array_index += len;
2360 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2361 is->sample_array_index = 0;
2366 /* return the wanted number of samples to get better sync if sync_type is video
2367 * or external master clock */
2368 static int synchronize_audio(VideoState *is, int nb_samples)
2370 int wanted_nb_samples = nb_samples;
2372 /* if not master, then we try to remove or add samples to correct the clock */
2373 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2374 double diff, avg_diff;
2375 int min_nb_samples, max_nb_samples;
2377 diff = get_clock(&is->audclk) - get_master_clock(is);
2379 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2380 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2381 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2382 /* not enough measures to have a correct estimate */
2383 is->audio_diff_avg_count++;
2385 /* estimate the A-V difference */
2386 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2388 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2389 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2390 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2391 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2392 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2394 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2395 diff, avg_diff, wanted_nb_samples - nb_samples,
2396 is->audio_clock, is->audio_diff_threshold);
2399 /* too big difference : may be initial PTS errors, so
2401 is->audio_diff_avg_count = 0;
2402 is->audio_diff_cum = 0;
2406 return wanted_nb_samples;
2410 * Decode one audio frame and return its uncompressed size.
2412 * The processed audio frame is decoded, converted if required, and
2413 * stored in is->audio_buf, with size in bytes given by the return
2416 static int audio_decode_frame(VideoState *is)
2418 int data_size, resampled_data_size;
2419 int64_t dec_channel_layout;
2420 av_unused double audio_clock0;
2421 int wanted_nb_samples;
2429 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2430 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2435 if (!(af = frame_queue_peek_readable(&is->sampq)))
2437 frame_queue_next(&is->sampq);
2438 } while (af->serial != is->audioq.serial);
2440 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2441 af->frame->nb_samples,
2442 af->frame->format, 1);
2444 dec_channel_layout =
2445 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2446 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2447 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2449 if (af->frame->format != is->audio_src.fmt ||
2450 dec_channel_layout != is->audio_src.channel_layout ||
2451 af->frame->sample_rate != is->audio_src.freq ||
2452 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2453 swr_free(&is->swr_ctx);
2454 is->swr_ctx = swr_alloc_set_opts(NULL,
2455 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2456 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2458 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2459 av_log(NULL, AV_LOG_ERROR,
2460 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2461 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2462 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2463 swr_free(&is->swr_ctx);
2466 is->audio_src.channel_layout = dec_channel_layout;
2467 is->audio_src.channels = av_frame_get_channels(af->frame);
2468 is->audio_src.freq = af->frame->sample_rate;
2469 is->audio_src.fmt = af->frame->format;
2473 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2474 uint8_t **out = &is->audio_buf1;
2475 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2476 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2479 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2482 if (wanted_nb_samples != af->frame->nb_samples) {
2483 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2484 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2485 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2489 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2490 if (!is->audio_buf1)
2491 return AVERROR(ENOMEM);
2492 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2494 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2497 if (len2 == out_count) {
2498 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2499 if (swr_init(is->swr_ctx) < 0)
2500 swr_free(&is->swr_ctx);
2502 is->audio_buf = is->audio_buf1;
2503 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2505 is->audio_buf = af->frame->data[0];
2506 resampled_data_size = data_size;
2509 audio_clock0 = is->audio_clock;
2510 /* update the audio clock with the pts */
2511 if (!isnan(af->pts))
2512 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2514 is->audio_clock = NAN;
2515 is->audio_clock_serial = af->serial;
2518 static double last_clock;
2519 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2520 is->audio_clock - last_clock,
2521 is->audio_clock, audio_clock0);
2522 last_clock = is->audio_clock;
2525 return resampled_data_size;
2528 /* prepare a new audio buffer */
2529 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2531 VideoState *is = opaque;
2532 int audio_size, len1;
2534 audio_callback_time = av_gettime_relative();
2537 if (is->audio_buf_index >= is->audio_buf_size) {
2538 audio_size = audio_decode_frame(is);
2539 if (audio_size < 0) {
2540 /* if error, just output silence */
2541 is->audio_buf = is->silence_buf;
2542 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2544 if (is->show_mode != SHOW_MODE_VIDEO)
2545 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2546 is->audio_buf_size = audio_size;
2548 is->audio_buf_index = 0;
2550 len1 = is->audio_buf_size - is->audio_buf_index;
2553 if (!is->muted && is->audio_volume == SDL_MIX_MAXVOLUME)
2554 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2556 memset(stream, is->silence_buf[0], len1);
2558 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2562 is->audio_buf_index += len1;
2564 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2565 /* Let's assume the audio driver that is used by SDL has two periods. */
2566 if (!isnan(is->audio_clock)) {
2567 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);
2568 sync_clock_to_slave(&is->extclk, &is->audclk);
2572 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2574 SDL_AudioSpec wanted_spec, spec;
2576 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2577 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2578 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2580 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2582 wanted_nb_channels = atoi(env);
2583 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2585 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2586 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2587 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2589 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2590 wanted_spec.channels = wanted_nb_channels;
2591 wanted_spec.freq = wanted_sample_rate;
2592 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2593 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2596 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2597 next_sample_rate_idx--;
2598 wanted_spec.format = AUDIO_S16SYS;
2599 wanted_spec.silence = 0;
2600 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2601 wanted_spec.callback = sdl_audio_callback;
2602 wanted_spec.userdata = opaque;
2603 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2604 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2605 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2606 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2607 if (!wanted_spec.channels) {
2608 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2609 wanted_spec.channels = wanted_nb_channels;
2610 if (!wanted_spec.freq) {
2611 av_log(NULL, AV_LOG_ERROR,
2612 "No more combinations to try, audio open failed\n");
2616 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2618 if (spec.format != AUDIO_S16SYS) {
2619 av_log(NULL, AV_LOG_ERROR,
2620 "SDL advised audio format %d is not supported!\n", spec.format);
2623 if (spec.channels != wanted_spec.channels) {
2624 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2625 if (!wanted_channel_layout) {
2626 av_log(NULL, AV_LOG_ERROR,
2627 "SDL advised channel count %d is not supported!\n", spec.channels);
2632 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2633 audio_hw_params->freq = spec.freq;
2634 audio_hw_params->channel_layout = wanted_channel_layout;
2635 audio_hw_params->channels = spec.channels;
2636 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2637 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);
2638 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2639 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2645 /* open a given stream. Return 0 if OK */
2646 static int stream_component_open(VideoState *is, int stream_index)
2648 AVFormatContext *ic = is->ic;
2649 AVCodecContext *avctx;
2651 const char *forced_codec_name = NULL;
2653 AVDictionaryEntry *t = NULL;
2654 int sample_rate, nb_channels;
2655 int64_t channel_layout;
2657 int stream_lowres = lowres;
2659 if (stream_index < 0 || stream_index >= ic->nb_streams)
2661 avctx = ic->streams[stream_index]->codec;
2663 codec = avcodec_find_decoder(avctx->codec_id);
2665 switch(avctx->codec_type){
2666 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2667 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2668 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2670 if (forced_codec_name)
2671 codec = avcodec_find_decoder_by_name(forced_codec_name);
2673 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2674 "No codec could be found with name '%s'\n", forced_codec_name);
2675 else av_log(NULL, AV_LOG_WARNING,
2676 "No codec could be found with id %d\n", avctx->codec_id);
2680 avctx->codec_id = codec->id;
2681 if(stream_lowres > av_codec_get_max_lowres(codec)){
2682 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2683 av_codec_get_max_lowres(codec));
2684 stream_lowres = av_codec_get_max_lowres(codec);
2686 av_codec_set_lowres(avctx, stream_lowres);
2689 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2692 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2694 if(codec->capabilities & AV_CODEC_CAP_DR1)
2695 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2698 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2699 if (!av_dict_get(opts, "threads", NULL, 0))
2700 av_dict_set(&opts, "threads", "auto", 0);
2702 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2703 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2704 av_dict_set(&opts, "refcounted_frames", "1", 0);
2705 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2708 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2709 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2710 ret = AVERROR_OPTION_NOT_FOUND;
2715 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2716 switch (avctx->codec_type) {
2717 case AVMEDIA_TYPE_AUDIO:
2722 is->audio_filter_src.freq = avctx->sample_rate;
2723 is->audio_filter_src.channels = avctx->channels;
2724 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2725 is->audio_filter_src.fmt = avctx->sample_fmt;
2726 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2728 link = is->out_audio_filter->inputs[0];
2729 sample_rate = link->sample_rate;
2730 nb_channels = link->channels;
2731 channel_layout = link->channel_layout;
2734 sample_rate = avctx->sample_rate;
2735 nb_channels = avctx->channels;
2736 channel_layout = avctx->channel_layout;
2739 /* prepare audio output */
2740 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2742 is->audio_hw_buf_size = ret;
2743 is->audio_src = is->audio_tgt;
2744 is->audio_buf_size = 0;
2745 is->audio_buf_index = 0;
2747 /* init averaging filter */
2748 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2749 is->audio_diff_avg_count = 0;
2750 /* since we do not have a precise anough audio fifo fullness,
2751 we correct audio sync only if larger than this threshold */
2752 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2754 is->audio_stream = stream_index;
2755 is->audio_st = ic->streams[stream_index];
2757 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2758 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2759 is->auddec.start_pts = is->audio_st->start_time;
2760 is->auddec.start_pts_tb = is->audio_st->time_base;
2762 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2766 case AVMEDIA_TYPE_VIDEO:
2767 is->video_stream = stream_index;
2768 is->video_st = ic->streams[stream_index];
2770 is->viddec_width = avctx->width;
2771 is->viddec_height = avctx->height;
2773 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2774 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2776 is->queue_attachments_req = 1;
2778 case AVMEDIA_TYPE_SUBTITLE:
2779 is->subtitle_stream = stream_index;
2780 is->subtitle_st = ic->streams[stream_index];
2782 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2783 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2791 av_dict_free(&opts);
2796 static int decode_interrupt_cb(void *ctx)
2798 VideoState *is = ctx;
2799 return is->abort_request;
2802 static int is_realtime(AVFormatContext *s)
2804 if( !strcmp(s->iformat->name, "rtp")
2805 || !strcmp(s->iformat->name, "rtsp")
2806 || !strcmp(s->iformat->name, "sdp")
2810 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2811 || !strncmp(s->filename, "udp:", 4)
2818 /* this thread gets the stream from the disk or the network */
2819 static int read_thread(void *arg)
2821 VideoState *is = arg;
2822 AVFormatContext *ic = NULL;
2824 int st_index[AVMEDIA_TYPE_NB];
2825 AVPacket pkt1, *pkt = &pkt1;
2826 int64_t stream_start_time;
2827 int pkt_in_play_range = 0;
2828 AVDictionaryEntry *t;
2829 AVDictionary **opts;
2830 int orig_nb_streams;
2831 SDL_mutex *wait_mutex = SDL_CreateMutex();
2832 int scan_all_pmts_set = 0;
2836 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2837 ret = AVERROR(ENOMEM);
2841 memset(st_index, -1, sizeof(st_index));
2842 is->last_video_stream = is->video_stream = -1;
2843 is->last_audio_stream = is->audio_stream = -1;
2844 is->last_subtitle_stream = is->subtitle_stream = -1;
2847 ic = avformat_alloc_context();
2849 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2850 ret = AVERROR(ENOMEM);
2853 ic->interrupt_callback.callback = decode_interrupt_cb;
2854 ic->interrupt_callback.opaque = is;
2855 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2856 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2857 scan_all_pmts_set = 1;
2859 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2861 print_error(is->filename, err);
2865 if (scan_all_pmts_set)
2866 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2868 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2869 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2870 ret = AVERROR_OPTION_NOT_FOUND;
2876 ic->flags |= AVFMT_FLAG_GENPTS;
2878 av_format_inject_global_side_data(ic);
2880 opts = setup_find_stream_info_opts(ic, codec_opts);
2881 orig_nb_streams = ic->nb_streams;
2883 err = avformat_find_stream_info(ic, opts);
2885 for (i = 0; i < orig_nb_streams; i++)
2886 av_dict_free(&opts[i]);
2890 av_log(NULL, AV_LOG_WARNING,
2891 "%s: could not find codec parameters\n", is->filename);
2897 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2899 if (seek_by_bytes < 0)
2900 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2902 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2904 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2905 window_title = av_asprintf("%s - %s", t->value, input_filename);
2907 /* if seeking requested, we execute it */
2908 if (start_time != AV_NOPTS_VALUE) {
2911 timestamp = start_time;
2912 /* add the stream start time */
2913 if (ic->start_time != AV_NOPTS_VALUE)
2914 timestamp += ic->start_time;
2915 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2917 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2918 is->filename, (double)timestamp / AV_TIME_BASE);
2922 is->realtime = is_realtime(ic);
2925 av_dump_format(ic, 0, is->filename, 0);
2927 for (i = 0; i < ic->nb_streams; i++) {
2928 AVStream *st = ic->streams[i];
2929 enum AVMediaType type = st->codec->codec_type;
2930 st->discard = AVDISCARD_ALL;
2931 if (wanted_stream_spec[type] && st_index[type] == -1)
2932 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2935 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2936 if (wanted_stream_spec[i] && st_index[i] == -1) {
2937 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));
2938 st_index[i] = INT_MAX;
2943 st_index[AVMEDIA_TYPE_VIDEO] =
2944 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2945 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2947 st_index[AVMEDIA_TYPE_AUDIO] =
2948 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2949 st_index[AVMEDIA_TYPE_AUDIO],
2950 st_index[AVMEDIA_TYPE_VIDEO],
2952 if (!video_disable && !subtitle_disable)
2953 st_index[AVMEDIA_TYPE_SUBTITLE] =
2954 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2955 st_index[AVMEDIA_TYPE_SUBTITLE],
2956 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2957 st_index[AVMEDIA_TYPE_AUDIO] :
2958 st_index[AVMEDIA_TYPE_VIDEO]),
2961 is->show_mode = show_mode;
2962 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2963 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2964 AVCodecContext *avctx = st->codec;
2965 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2967 set_default_window_size(avctx->width, avctx->height, sar);
2970 /* open the streams */
2971 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2972 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2976 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2977 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2979 if (is->show_mode == SHOW_MODE_NONE)
2980 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2982 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2983 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2986 if (is->video_stream < 0 && is->audio_stream < 0) {
2987 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2993 if (infinite_buffer < 0 && is->realtime)
2994 infinite_buffer = 1;
2997 if (is->abort_request)
2999 if (is->paused != is->last_paused) {
3000 is->last_paused = is->paused;
3002 is->read_pause_return = av_read_pause(ic);
3006 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3008 (!strcmp(ic->iformat->name, "rtsp") ||
3009 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3010 /* wait 10 ms to avoid trying to get another packet */
3017 int64_t seek_target = is->seek_pos;
3018 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3019 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3020 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3021 // of the seek_pos/seek_rel variables
3023 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3025 av_log(NULL, AV_LOG_ERROR,
3026 "%s: error while seeking\n", is->ic->filename);
3028 if (is->audio_stream >= 0) {
3029 packet_queue_flush(&is->audioq);
3030 packet_queue_put(&is->audioq, &flush_pkt);
3032 if (is->subtitle_stream >= 0) {
3033 packet_queue_flush(&is->subtitleq);
3034 packet_queue_put(&is->subtitleq, &flush_pkt);
3036 if (is->video_stream >= 0) {
3037 packet_queue_flush(&is->videoq);
3038 packet_queue_put(&is->videoq, &flush_pkt);
3040 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3041 set_clock(&is->extclk, NAN, 0);
3043 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3047 is->queue_attachments_req = 1;
3050 step_to_next_frame(is);
3052 if (is->queue_attachments_req) {
3053 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3055 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3057 packet_queue_put(&is->videoq, ©);
3058 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3060 is->queue_attachments_req = 0;
3063 /* if the queue are full, no need to read more */
3064 if (infinite_buffer<1 &&
3065 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3066 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3067 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3068 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3069 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3071 SDL_LockMutex(wait_mutex);
3072 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3073 SDL_UnlockMutex(wait_mutex);
3077 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3078 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3079 if (loop != 1 && (!loop || --loop)) {
3080 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3081 } else if (autoexit) {
3086 ret = av_read_frame(ic, pkt);
3088 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3089 if (is->video_stream >= 0)
3090 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3091 if (is->audio_stream >= 0)
3092 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3093 if (is->subtitle_stream >= 0)
3094 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3097 if (ic->pb && ic->pb->error)
3099 SDL_LockMutex(wait_mutex);
3100 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3101 SDL_UnlockMutex(wait_mutex);
3106 /* check if packet is in play range specified by user, then queue, otherwise discard */
3107 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3108 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3109 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3110 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3111 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3112 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3113 <= ((double)duration / 1000000);
3114 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3115 packet_queue_put(&is->audioq, pkt);
3116 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3117 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3118 packet_queue_put(&is->videoq, pkt);
3119 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3120 packet_queue_put(&is->subtitleq, pkt);
3122 av_free_packet(pkt);
3129 avformat_close_input(&ic);
3134 event.type = FF_QUIT_EVENT;
3135 event.user.data1 = is;
3136 SDL_PushEvent(&event);
3138 SDL_DestroyMutex(wait_mutex);
3142 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3146 is = av_mallocz(sizeof(VideoState));
3149 is->filename = av_strdup(filename);
3152 is->iformat = iformat;
3156 /* start video display */
3157 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3159 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3161 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3164 if (packet_queue_init(&is->videoq) < 0 ||
3165 packet_queue_init(&is->audioq) < 0 ||
3166 packet_queue_init(&is->subtitleq) < 0)
3169 if (!(is->continue_read_thread = SDL_CreateCond())) {
3170 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3174 init_clock(&is->vidclk, &is->videoq.serial);
3175 init_clock(&is->audclk, &is->audioq.serial);
3176 init_clock(&is->extclk, &is->extclk.serial);
3177 is->audio_clock_serial = -1;
3178 is->audio_volume = SDL_MIX_MAXVOLUME;
3180 is->av_sync_type = av_sync_type;
3181 is->read_tid = SDL_CreateThread(read_thread, is);
3182 if (!is->read_tid) {
3183 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3191 static void stream_cycle_channel(VideoState *is, int codec_type)
3193 AVFormatContext *ic = is->ic;
3194 int start_index, stream_index;
3197 AVProgram *p = NULL;
3198 int nb_streams = is->ic->nb_streams;
3200 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3201 start_index = is->last_video_stream;
3202 old_index = is->video_stream;
3203 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3204 start_index = is->last_audio_stream;
3205 old_index = is->audio_stream;
3207 start_index = is->last_subtitle_stream;
3208 old_index = is->subtitle_stream;
3210 stream_index = start_index;
3212 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3213 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3215 nb_streams = p->nb_stream_indexes;
3216 for (start_index = 0; start_index < nb_streams; start_index++)
3217 if (p->stream_index[start_index] == stream_index)
3219 if (start_index == nb_streams)
3221 stream_index = start_index;
3226 if (++stream_index >= nb_streams)
3228 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3231 is->last_subtitle_stream = -1;
3234 if (start_index == -1)
3238 if (stream_index == start_index)
3240 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3241 if (st->codec->codec_type == codec_type) {
3242 /* check that parameters are OK */
3243 switch (codec_type) {
3244 case AVMEDIA_TYPE_AUDIO:
3245 if (st->codec->sample_rate != 0 &&
3246 st->codec->channels != 0)
3249 case AVMEDIA_TYPE_VIDEO:
3250 case AVMEDIA_TYPE_SUBTITLE:
3258 if (p && stream_index != -1)
3259 stream_index = p->stream_index[stream_index];
3260 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3261 av_get_media_type_string(codec_type),
3265 stream_component_close(is, old_index);
3266 stream_component_open(is, stream_index);
3270 static void toggle_full_screen(VideoState *is)
3272 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3273 /* OS X needs to reallocate the SDL overlays */
3275 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3276 is->pictq.queue[i].reallocate = 1;
3278 is_full_screen = !is_full_screen;
3279 video_open(is, 1, NULL);
3282 static void toggle_audio_display(VideoState *is)
3284 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3285 int next = is->show_mode;
3287 next = (next + 1) % SHOW_MODE_NB;
3288 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3289 if (is->show_mode != next) {
3290 fill_rectangle(screen,
3291 is->xleft, is->ytop, is->width, is->height,
3293 is->force_refresh = 1;
3294 is->show_mode = next;
3298 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3299 double remaining_time = 0.0;
3301 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3302 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3306 if (remaining_time > 0.0)
3307 av_usleep((int64_t)(remaining_time * 1000000.0));
3308 remaining_time = REFRESH_RATE;
3309 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3310 video_refresh(is, &remaining_time);
3315 static void seek_chapter(VideoState *is, int incr)
3317 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3320 if (!is->ic->nb_chapters)
3323 /* find the current chapter */
3324 for (i = 0; i < is->ic->nb_chapters; i++) {
3325 AVChapter *ch = is->ic->chapters[i];
3326 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3334 if (i >= is->ic->nb_chapters)
3337 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3338 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3339 AV_TIME_BASE_Q), 0, 0);
3342 /* handle an event sent by the GUI */
3343 static void event_loop(VideoState *cur_stream)
3346 double incr, pos, frac;
3350 refresh_loop_wait_event(cur_stream, &event);
3351 switch (event.type) {
3353 if (exit_on_keydown) {
3354 do_exit(cur_stream);
3357 switch (event.key.keysym.sym) {
3360 do_exit(cur_stream);
3363 toggle_full_screen(cur_stream);
3364 cur_stream->force_refresh = 1;
3368 toggle_pause(cur_stream);
3371 toggle_mute(cur_stream);
3373 case SDLK_KP_MULTIPLY:
3375 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3377 case SDLK_KP_DIVIDE:
3379 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3381 case SDLK_s: // S: Step to next frame
3382 step_to_next_frame(cur_stream);
3385 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3388 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3391 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3392 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3393 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3396 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3400 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3401 if (++cur_stream->vfilter_idx >= nb_vfilters)
3402 cur_stream->vfilter_idx = 0;
3404 cur_stream->vfilter_idx = 0;
3405 toggle_audio_display(cur_stream);
3408 toggle_audio_display(cur_stream);
3412 if (cur_stream->ic->nb_chapters <= 1) {
3416 seek_chapter(cur_stream, 1);
3419 if (cur_stream->ic->nb_chapters <= 1) {
3423 seek_chapter(cur_stream, -1);
3437 if (seek_by_bytes) {
3439 if (pos < 0 && cur_stream->video_stream >= 0)
3440 pos = frame_queue_last_pos(&cur_stream->pictq);
3441 if (pos < 0 && cur_stream->audio_stream >= 0)
3442 pos = frame_queue_last_pos(&cur_stream->sampq);
3444 pos = avio_tell(cur_stream->ic->pb);
3445 if (cur_stream->ic->bit_rate)
3446 incr *= cur_stream->ic->bit_rate / 8.0;
3450 stream_seek(cur_stream, pos, incr, 1);
3452 pos = get_master_clock(cur_stream);
3454 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3456 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3457 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3458 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3465 case SDL_VIDEOEXPOSE:
3466 cur_stream->force_refresh = 1;
3468 case SDL_MOUSEBUTTONDOWN:
3469 if (exit_on_mousedown) {
3470 do_exit(cur_stream);
3473 case SDL_MOUSEMOTION:
3474 if (cursor_hidden) {
3478 cursor_last_shown = av_gettime_relative();
3479 if (event.type == SDL_MOUSEBUTTONDOWN) {
3482 if (event.motion.state != SDL_PRESSED)
3486 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3487 uint64_t size = avio_size(cur_stream->ic->pb);
3488 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3492 int tns, thh, tmm, tss;
3493 tns = cur_stream->ic->duration / 1000000LL;
3495 tmm = (tns % 3600) / 60;
3497 frac = x / cur_stream->width;
3500 mm = (ns % 3600) / 60;
3502 av_log(NULL, AV_LOG_INFO,
3503 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3504 hh, mm, ss, thh, tmm, tss);
3505 ts = frac * cur_stream->ic->duration;
3506 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3507 ts += cur_stream->ic->start_time;
3508 stream_seek(cur_stream, ts, 0, 0);
3511 case SDL_VIDEORESIZE:
3512 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3513 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3515 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3516 do_exit(cur_stream);
3518 screen_width = cur_stream->width = screen->w;
3519 screen_height = cur_stream->height = screen->h;
3520 cur_stream->force_refresh = 1;
3524 do_exit(cur_stream);
3526 case FF_ALLOC_EVENT:
3527 alloc_picture(event.user.data1);
3535 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3537 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3538 return opt_default(NULL, "video_size", arg);
3541 static int opt_width(void *optctx, const char *opt, const char *arg)
3543 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3547 static int opt_height(void *optctx, const char *opt, const char *arg)
3549 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3553 static int opt_format(void *optctx, const char *opt, const char *arg)
3555 file_iformat = av_find_input_format(arg);
3556 if (!file_iformat) {
3557 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3558 return AVERROR(EINVAL);
3563 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3565 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3566 return opt_default(NULL, "pixel_format", arg);
3569 static int opt_sync(void *optctx, const char *opt, const char *arg)
3571 if (!strcmp(arg, "audio"))
3572 av_sync_type = AV_SYNC_AUDIO_MASTER;
3573 else if (!strcmp(arg, "video"))
3574 av_sync_type = AV_SYNC_VIDEO_MASTER;
3575 else if (!strcmp(arg, "ext"))
3576 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3578 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3584 static int opt_seek(void *optctx, const char *opt, const char *arg)
3586 start_time = parse_time_or_die(opt, arg, 1);
3590 static int opt_duration(void *optctx, const char *opt, const char *arg)
3592 duration = parse_time_or_die(opt, arg, 1);
3596 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3598 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3599 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3600 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3601 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3605 static void opt_input_file(void *optctx, const char *filename)
3607 if (input_filename) {
3608 av_log(NULL, AV_LOG_FATAL,
3609 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3610 filename, input_filename);
3613 if (!strcmp(filename, "-"))
3615 input_filename = filename;
3618 static int opt_codec(void *optctx, const char *opt, const char *arg)
3620 const char *spec = strchr(opt, ':');
3622 av_log(NULL, AV_LOG_ERROR,
3623 "No media specifier was specified in '%s' in option '%s'\n",
3625 return AVERROR(EINVAL);
3629 case 'a' : audio_codec_name = arg; break;
3630 case 's' : subtitle_codec_name = arg; break;
3631 case 'v' : video_codec_name = arg; break;
3633 av_log(NULL, AV_LOG_ERROR,
3634 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3635 return AVERROR(EINVAL);
3642 static const OptionDef options[] = {
3643 #include "cmdutils_common_opts.h"
3644 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3645 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3646 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3647 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3648 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3649 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3650 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3651 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3652 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3653 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3654 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3655 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3656 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3657 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3658 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3659 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3660 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3661 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3662 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3663 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3664 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3665 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3666 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3667 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3668 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3669 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3670 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3671 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3672 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3674 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3675 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3677 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3678 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3679 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3680 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3681 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3682 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3683 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3684 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3685 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3689 static void show_usage(void)
3691 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3692 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3693 av_log(NULL, AV_LOG_INFO, "\n");
3696 void show_help_default(const char *opt, const char *arg)
3698 av_log_set_callback(log_callback_help);
3700 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3701 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3703 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3704 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3705 #if !CONFIG_AVFILTER
3706 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3708 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3710 printf("\nWhile playing:\n"
3712 "f toggle full screen\n"
3715 "9, 0 decrease and increase volume respectively\n"
3716 "/, * decrease and increase volume respectively\n"
3717 "a cycle audio channel in the current program\n"
3718 "v cycle video channel\n"
3719 "t cycle subtitle channel in the current program\n"
3721 "w cycle video filters or show modes\n"
3722 "s activate frame-step mode\n"
3723 "left/right seek backward/forward 10 seconds\n"
3724 "down/up seek backward/forward 1 minute\n"
3725 "page down/page up seek backward/forward 10 minutes\n"
3726 "mouse click seek to percentage in file corresponding to fraction of width\n"
3730 static int lockmgr(void **mtx, enum AVLockOp op)
3733 case AV_LOCK_CREATE:
3734 *mtx = SDL_CreateMutex();
3736 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3740 case AV_LOCK_OBTAIN:
3741 return !!SDL_LockMutex(*mtx);
3742 case AV_LOCK_RELEASE:
3743 return !!SDL_UnlockMutex(*mtx);
3744 case AV_LOCK_DESTROY:
3745 SDL_DestroyMutex(*mtx);
3751 /* Called from the main */
3752 int main(int argc, char **argv)
3756 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3758 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3759 parse_loglevel(argc, argv, options);
3761 /* register all codecs, demux and protocols */
3763 avdevice_register_all();
3766 avfilter_register_all();
3769 avformat_network_init();
3773 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3774 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3776 show_banner(argc, argv, options);
3778 parse_options(NULL, argc, argv, options, opt_input_file);
3780 if (!input_filename) {
3782 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3783 av_log(NULL, AV_LOG_FATAL,
3784 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3788 if (display_disable) {
3791 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3793 flags &= ~SDL_INIT_AUDIO;
3794 if (display_disable)
3795 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3796 #if !defined(_WIN32) && !defined(__APPLE__)
3797 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3799 if (SDL_Init (flags)) {
3800 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3801 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3805 if (!display_disable) {
3806 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3807 fs_screen_width = vi->current_w;
3808 fs_screen_height = vi->current_h;
3811 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3812 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3813 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3815 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3817 if (av_lockmgr_register(lockmgr)) {
3818 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3822 av_init_packet(&flush_pkt);
3823 flush_pkt.data = (uint8_t *)&flush_pkt;
3825 is = stream_open(input_filename, file_iformat);
3827 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");