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 {
154 AVSubtitleRect **subrects; /* rescaled subtitle rectangles in yuva */
156 double pts; /* presentation timestamp for the frame */
157 double duration; /* estimated duration of the frame */
158 int64_t pos; /* byte position of the frame in the input file */
167 typedef struct FrameQueue {
168 Frame queue[FRAME_QUEUE_SIZE];
181 AV_SYNC_AUDIO_MASTER, /* default choice */
182 AV_SYNC_VIDEO_MASTER,
183 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
186 typedef struct Decoder {
190 AVCodecContext *avctx;
194 SDL_cond *empty_queue_cond;
196 AVRational start_pts_tb;
198 AVRational next_pts_tb;
199 SDL_Thread *decoder_tid;
202 typedef struct VideoState {
203 SDL_Thread *read_tid;
204 AVInputFormat *iformat;
209 int queue_attachments_req;
214 int read_pause_return;
238 int audio_clock_serial;
239 double audio_diff_cum; /* used for AV difference average computation */
240 double audio_diff_avg_coef;
241 double audio_diff_threshold;
242 int audio_diff_avg_count;
245 int audio_hw_buf_size;
246 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
249 unsigned int audio_buf_size; /* in bytes */
250 unsigned int audio_buf1_size;
251 int audio_buf_index; /* in bytes */
252 int audio_write_buf_size;
255 struct AudioParams audio_src;
257 struct AudioParams audio_filter_src;
259 struct AudioParams audio_tgt;
260 struct SwrContext *swr_ctx;
261 int frame_drops_early;
262 int frame_drops_late;
265 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
267 int16_t sample_array[SAMPLE_ARRAY_SIZE];
268 int sample_array_index;
272 FFTSample *rdft_data;
274 double last_vis_time;
277 AVStream *subtitle_st;
278 PacketQueue subtitleq;
281 double frame_last_returned_time;
282 double frame_last_filter_delay;
286 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
288 struct SwsContext *img_convert_ctx;
290 struct SwsContext *sub_convert_ctx;
291 SDL_Rect last_display_rect;
295 int width, height, xleft, ytop;
300 AVFilterContext *in_video_filter; // the first filter in the video chain
301 AVFilterContext *out_video_filter; // the last filter in the video chain
302 AVFilterContext *in_audio_filter; // the first filter in the audio chain
303 AVFilterContext *out_audio_filter; // the last filter in the audio chain
304 AVFilterGraph *agraph; // audio filter graph
307 int last_video_stream, last_audio_stream, last_subtitle_stream;
309 SDL_cond *continue_read_thread;
312 /* options specified by the user */
313 static AVInputFormat *file_iformat;
314 static const char *input_filename;
315 static const char *window_title;
316 static int fs_screen_width;
317 static int fs_screen_height;
318 static int default_width = 640;
319 static int default_height = 480;
320 static int screen_width = 0;
321 static int screen_height = 0;
322 static int audio_disable;
323 static int video_disable;
324 static int subtitle_disable;
325 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
326 static int seek_by_bytes = -1;
327 static int display_disable;
328 static int show_status = 1;
329 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
330 static int64_t start_time = AV_NOPTS_VALUE;
331 static int64_t duration = AV_NOPTS_VALUE;
333 static int genpts = 0;
334 static int lowres = 0;
335 static int decoder_reorder_pts = -1;
337 static int exit_on_keydown;
338 static int exit_on_mousedown;
340 static int framedrop = -1;
341 static int infinite_buffer = -1;
342 static enum ShowMode show_mode = SHOW_MODE_NONE;
343 static const char *audio_codec_name;
344 static const char *subtitle_codec_name;
345 static const char *video_codec_name;
346 double rdftspeed = 0.02;
347 static int64_t cursor_last_shown;
348 static int cursor_hidden = 0;
350 static const char **vfilters_list = NULL;
351 static int nb_vfilters = 0;
352 static char *afilters = NULL;
354 static int autorotate = 1;
356 /* current context */
357 static int is_full_screen;
358 static int64_t audio_callback_time;
360 static AVPacket flush_pkt;
362 #define FF_ALLOC_EVENT (SDL_USEREVENT)
363 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
365 static SDL_Surface *screen;
368 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
370 GROW_ARRAY(vfilters_list, nb_vfilters);
371 vfilters_list[nb_vfilters - 1] = arg;
377 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
378 enum AVSampleFormat fmt2, int64_t channel_count2)
380 /* If channel count == 1, planar and non-planar formats are the same */
381 if (channel_count1 == 1 && channel_count2 == 1)
382 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
384 return channel_count1 != channel_count2 || fmt1 != fmt2;
388 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
390 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
391 return channel_layout;
396 static void free_picture(Frame *vp);
398 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
400 MyAVPacketList *pkt1;
402 if (q->abort_request)
405 pkt1 = av_malloc(sizeof(MyAVPacketList));
410 if (pkt == &flush_pkt)
412 pkt1->serial = q->serial;
417 q->last_pkt->next = pkt1;
420 q->size += pkt1->pkt.size + sizeof(*pkt1);
421 /* XXX: should duplicate packet data in DV case */
422 SDL_CondSignal(q->cond);
426 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
430 /* duplicate the packet */
431 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
434 SDL_LockMutex(q->mutex);
435 ret = packet_queue_put_private(q, pkt);
436 SDL_UnlockMutex(q->mutex);
438 if (pkt != &flush_pkt && ret < 0)
444 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
446 AVPacket pkt1, *pkt = &pkt1;
450 pkt->stream_index = stream_index;
451 return packet_queue_put(q, pkt);
454 /* packet queue handling */
455 static int packet_queue_init(PacketQueue *q)
457 memset(q, 0, sizeof(PacketQueue));
458 q->mutex = SDL_CreateMutex();
460 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
461 return AVERROR(ENOMEM);
463 q->cond = SDL_CreateCond();
465 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
466 return AVERROR(ENOMEM);
468 q->abort_request = 1;
472 static void packet_queue_flush(PacketQueue *q)
474 MyAVPacketList *pkt, *pkt1;
476 SDL_LockMutex(q->mutex);
477 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
479 av_free_packet(&pkt->pkt);
486 SDL_UnlockMutex(q->mutex);
489 static void packet_queue_destroy(PacketQueue *q)
491 packet_queue_flush(q);
492 SDL_DestroyMutex(q->mutex);
493 SDL_DestroyCond(q->cond);
496 static void packet_queue_abort(PacketQueue *q)
498 SDL_LockMutex(q->mutex);
500 q->abort_request = 1;
502 SDL_CondSignal(q->cond);
504 SDL_UnlockMutex(q->mutex);
507 static void packet_queue_start(PacketQueue *q)
509 SDL_LockMutex(q->mutex);
510 q->abort_request = 0;
511 packet_queue_put_private(q, &flush_pkt);
512 SDL_UnlockMutex(q->mutex);
515 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
516 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
518 MyAVPacketList *pkt1;
521 SDL_LockMutex(q->mutex);
524 if (q->abort_request) {
531 q->first_pkt = pkt1->next;
535 q->size -= pkt1->pkt.size + sizeof(*pkt1);
538 *serial = pkt1->serial;
546 SDL_CondWait(q->cond, q->mutex);
549 SDL_UnlockMutex(q->mutex);
553 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
554 memset(d, 0, sizeof(Decoder));
557 d->empty_queue_cond = empty_queue_cond;
558 d->start_pts = AV_NOPTS_VALUE;
561 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
567 if (d->queue->abort_request)
570 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
573 if (d->queue->nb_packets == 0)
574 SDL_CondSignal(d->empty_queue_cond);
575 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
577 if (pkt.data == flush_pkt.data) {
578 avcodec_flush_buffers(d->avctx);
580 d->next_pts = d->start_pts;
581 d->next_pts_tb = d->start_pts_tb;
583 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
584 av_free_packet(&d->pkt);
585 d->pkt_temp = d->pkt = pkt;
586 d->packet_pending = 1;
589 switch (d->avctx->codec_type) {
590 case AVMEDIA_TYPE_VIDEO:
591 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
593 if (decoder_reorder_pts == -1) {
594 frame->pts = av_frame_get_best_effort_timestamp(frame);
595 } else if (decoder_reorder_pts) {
596 frame->pts = frame->pkt_pts;
598 frame->pts = frame->pkt_dts;
602 case AVMEDIA_TYPE_AUDIO:
603 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
605 AVRational tb = (AVRational){1, frame->sample_rate};
606 if (frame->pts != AV_NOPTS_VALUE)
607 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
608 else if (frame->pkt_pts != AV_NOPTS_VALUE)
609 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
610 else if (d->next_pts != AV_NOPTS_VALUE)
611 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
612 if (frame->pts != AV_NOPTS_VALUE) {
613 d->next_pts = frame->pts + frame->nb_samples;
618 case AVMEDIA_TYPE_SUBTITLE:
619 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
624 d->packet_pending = 0;
627 d->pkt_temp.pts = AV_NOPTS_VALUE;
628 if (d->pkt_temp.data) {
629 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
630 ret = d->pkt_temp.size;
631 d->pkt_temp.data += ret;
632 d->pkt_temp.size -= ret;
633 if (d->pkt_temp.size <= 0)
634 d->packet_pending = 0;
637 d->packet_pending = 0;
638 d->finished = d->pkt_serial;
642 } while (!got_frame && !d->finished);
647 static void decoder_destroy(Decoder *d) {
648 av_free_packet(&d->pkt);
651 static void frame_queue_unref_item(Frame *vp)
654 for (i = 0; i < vp->sub.num_rects; i++) {
655 av_freep(&vp->subrects[i]->data[0]);
656 av_freep(&vp->subrects[i]);
658 av_freep(&vp->subrects);
659 av_frame_unref(vp->frame);
660 avsubtitle_free(&vp->sub);
663 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
666 memset(f, 0, sizeof(FrameQueue));
667 if (!(f->mutex = SDL_CreateMutex())) {
668 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
669 return AVERROR(ENOMEM);
671 if (!(f->cond = SDL_CreateCond())) {
672 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
673 return AVERROR(ENOMEM);
676 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
677 f->keep_last = !!keep_last;
678 for (i = 0; i < f->max_size; i++)
679 if (!(f->queue[i].frame = av_frame_alloc()))
680 return AVERROR(ENOMEM);
684 static void frame_queue_destory(FrameQueue *f)
687 for (i = 0; i < f->max_size; i++) {
688 Frame *vp = &f->queue[i];
689 frame_queue_unref_item(vp);
690 av_frame_free(&vp->frame);
693 SDL_DestroyMutex(f->mutex);
694 SDL_DestroyCond(f->cond);
697 static void frame_queue_signal(FrameQueue *f)
699 SDL_LockMutex(f->mutex);
700 SDL_CondSignal(f->cond);
701 SDL_UnlockMutex(f->mutex);
704 static Frame *frame_queue_peek(FrameQueue *f)
706 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
709 static Frame *frame_queue_peek_next(FrameQueue *f)
711 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
714 static Frame *frame_queue_peek_last(FrameQueue *f)
716 return &f->queue[f->rindex];
719 static Frame *frame_queue_peek_writable(FrameQueue *f)
721 /* wait until we have space to put a new frame */
722 SDL_LockMutex(f->mutex);
723 while (f->size >= f->max_size &&
724 !f->pktq->abort_request) {
725 SDL_CondWait(f->cond, f->mutex);
727 SDL_UnlockMutex(f->mutex);
729 if (f->pktq->abort_request)
732 return &f->queue[f->windex];
735 static Frame *frame_queue_peek_readable(FrameQueue *f)
737 /* wait until we have a readable a new frame */
738 SDL_LockMutex(f->mutex);
739 while (f->size - f->rindex_shown <= 0 &&
740 !f->pktq->abort_request) {
741 SDL_CondWait(f->cond, f->mutex);
743 SDL_UnlockMutex(f->mutex);
745 if (f->pktq->abort_request)
748 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
751 static void frame_queue_push(FrameQueue *f)
753 if (++f->windex == f->max_size)
755 SDL_LockMutex(f->mutex);
757 SDL_CondSignal(f->cond);
758 SDL_UnlockMutex(f->mutex);
761 static void frame_queue_next(FrameQueue *f)
763 if (f->keep_last && !f->rindex_shown) {
767 frame_queue_unref_item(&f->queue[f->rindex]);
768 if (++f->rindex == f->max_size)
770 SDL_LockMutex(f->mutex);
772 SDL_CondSignal(f->cond);
773 SDL_UnlockMutex(f->mutex);
776 /* jump back to the previous frame if available by resetting rindex_shown */
777 static int frame_queue_prev(FrameQueue *f)
779 int ret = f->rindex_shown;
784 /* return the number of undisplayed frames in the queue */
785 static int frame_queue_nb_remaining(FrameQueue *f)
787 return f->size - f->rindex_shown;
790 /* return last shown position */
791 static int64_t frame_queue_last_pos(FrameQueue *f)
793 Frame *fp = &f->queue[f->rindex];
794 if (f->rindex_shown && fp->serial == f->pktq->serial)
800 static void decoder_abort(Decoder *d, FrameQueue *fq)
802 packet_queue_abort(d->queue);
803 frame_queue_signal(fq);
804 SDL_WaitThread(d->decoder_tid, NULL);
805 d->decoder_tid = NULL;
806 packet_queue_flush(d->queue);
809 static inline void fill_rectangle(SDL_Surface *screen,
810 int x, int y, int w, int h, int color, int update)
817 SDL_FillRect(screen, &rect, color);
818 if (update && w > 0 && h > 0)
819 SDL_UpdateRect(screen, x, y, w, h);
822 /* draw only the border of a rectangle */
823 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
827 /* fill the background */
831 w2 = width - (x + w);
837 h2 = height - (y + h);
840 fill_rectangle(screen,
844 fill_rectangle(screen,
845 xleft + width - w2, ytop,
848 fill_rectangle(screen,
852 fill_rectangle(screen,
853 xleft + w1, ytop + height - h2,
858 #define ALPHA_BLEND(a, oldp, newp, s)\
859 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
865 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
867 int x, y, Y, U, V, A;
868 uint8_t *lum, *cb, *cr;
869 int dstx, dsty, dstw, dsth;
870 const AVSubtitleRect *src = rect;
872 dstw = av_clip(rect->w, 0, imgw);
873 dsth = av_clip(rect->h, 0, imgh);
874 dstx = av_clip(rect->x, 0, imgw - dstw);
875 dsty = av_clip(rect->y, 0, imgh - dsth);
876 lum = dst->data[0] + dstx + dsty * dst->linesize[0];
877 cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
878 cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
880 for (y = 0; y<dsth; y++) {
881 for (x = 0; x<dstw; x++) {
882 Y = src->data[0][x + y*src->linesize[0]];
883 A = src->data[3][x + y*src->linesize[3]];
884 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
887 lum += dst->linesize[0] - dstw;
890 for (y = 0; y<dsth/2; y++) {
891 for (x = 0; x<dstw/2; x++) {
892 U = src->data[1][x + y*src->linesize[1]];
893 V = src->data[2][x + y*src->linesize[2]];
894 A = src->data[3][2*x + 2*y *src->linesize[3]]
895 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
896 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
897 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
898 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
899 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
903 cb += dst->linesize[1] - dstw/2;
904 cr += dst->linesize[2] - dstw/2;
908 static void free_picture(Frame *vp)
911 SDL_FreeYUVOverlay(vp->bmp);
916 static void calculate_display_rect(SDL_Rect *rect,
917 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
918 int pic_width, int pic_height, AVRational pic_sar)
921 int width, height, x, y;
923 if (pic_sar.num == 0)
926 aspect_ratio = av_q2d(pic_sar);
928 if (aspect_ratio <= 0.0)
930 aspect_ratio *= (float)pic_width / (float)pic_height;
932 /* XXX: we suppose the screen has a 1.0 pixel ratio */
934 width = ((int)rint(height * aspect_ratio)) & ~1;
935 if (width > scr_width) {
937 height = ((int)rint(width / aspect_ratio)) & ~1;
939 x = (scr_width - width) / 2;
940 y = (scr_height - height) / 2;
941 rect->x = scr_xleft + x;
942 rect->y = scr_ytop + y;
943 rect->w = FFMAX(width, 1);
944 rect->h = FFMAX(height, 1);
947 static void video_image_display(VideoState *is)
955 vp = frame_queue_peek(&is->pictq);
957 if (is->subtitle_st) {
958 if (frame_queue_nb_remaining(&is->subpq) > 0) {
959 sp = frame_queue_peek(&is->subpq);
961 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
962 SDL_LockYUVOverlay (vp->bmp);
964 pict.data[0] = vp->bmp->pixels[0];
965 pict.data[1] = vp->bmp->pixels[2];
966 pict.data[2] = vp->bmp->pixels[1];
968 pict.linesize[0] = vp->bmp->pitches[0];
969 pict.linesize[1] = vp->bmp->pitches[2];
970 pict.linesize[2] = vp->bmp->pitches[1];
972 for (i = 0; i < sp->sub.num_rects; i++)
973 blend_subrect(&pict, sp->subrects[i],
974 vp->bmp->w, vp->bmp->h);
976 SDL_UnlockYUVOverlay (vp->bmp);
981 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
983 SDL_DisplayYUVOverlay(vp->bmp, &rect);
985 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) {
986 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
987 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
988 is->last_display_rect = rect;
993 static inline int compute_mod(int a, int b)
995 return a < 0 ? a%b + b : a%b;
998 static void video_audio_display(VideoState *s)
1000 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1001 int ch, channels, h, h2, bgcolor, fgcolor;
1003 int rdft_bits, nb_freq;
1005 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1007 nb_freq = 1 << (rdft_bits - 1);
1009 /* compute display index : center on currently output samples */
1010 channels = s->audio_tgt.channels;
1011 nb_display_channels = channels;
1013 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1015 delay = s->audio_write_buf_size;
1018 /* to be more precise, we take into account the time spent since
1019 the last buffer computation */
1020 if (audio_callback_time) {
1021 time_diff = av_gettime_relative() - audio_callback_time;
1022 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1025 delay += 2 * data_used;
1026 if (delay < data_used)
1029 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1030 if (s->show_mode == SHOW_MODE_WAVES) {
1032 for (i = 0; i < 1000; i += channels) {
1033 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1034 int a = s->sample_array[idx];
1035 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1036 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1037 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1039 if (h < score && (b ^ c) < 0) {
1046 s->last_i_start = i_start;
1048 i_start = s->last_i_start;
1051 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1052 if (s->show_mode == SHOW_MODE_WAVES) {
1053 fill_rectangle(screen,
1054 s->xleft, s->ytop, s->width, s->height,
1057 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1059 /* total height for one channel */
1060 h = s->height / nb_display_channels;
1061 /* graph height / 2 */
1063 for (ch = 0; ch < nb_display_channels; ch++) {
1065 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1066 for (x = 0; x < s->width; x++) {
1067 y = (s->sample_array[i] * h2) >> 15;
1074 fill_rectangle(screen,
1075 s->xleft + x, ys, 1, y,
1078 if (i >= SAMPLE_ARRAY_SIZE)
1079 i -= SAMPLE_ARRAY_SIZE;
1083 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1085 for (ch = 1; ch < nb_display_channels; ch++) {
1086 y = s->ytop + ch * h;
1087 fill_rectangle(screen,
1088 s->xleft, y, s->width, 1,
1091 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1093 nb_display_channels= FFMIN(nb_display_channels, 2);
1094 if (rdft_bits != s->rdft_bits) {
1095 av_rdft_end(s->rdft);
1096 av_free(s->rdft_data);
1097 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1098 s->rdft_bits = rdft_bits;
1099 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1101 if (!s->rdft || !s->rdft_data){
1102 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1103 s->show_mode = SHOW_MODE_WAVES;
1106 for (ch = 0; ch < nb_display_channels; ch++) {
1107 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1109 for (x = 0; x < 2 * nb_freq; x++) {
1110 double w = (x-nb_freq) * (1.0 / nb_freq);
1111 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1113 if (i >= SAMPLE_ARRAY_SIZE)
1114 i -= SAMPLE_ARRAY_SIZE;
1116 av_rdft_calc(s->rdft, data[ch]);
1118 /* Least efficient way to do this, we should of course
1119 * directly access it but it is more than fast enough. */
1120 for (y = 0; y < s->height; y++) {
1121 double w = 1 / sqrt(nb_freq);
1122 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]));
1123 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1124 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1127 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1129 fill_rectangle(screen,
1130 s->xpos, s->height-y, 1, 1,
1134 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1137 if (s->xpos >= s->width)
1142 static void stream_component_close(VideoState *is, int stream_index)
1144 AVFormatContext *ic = is->ic;
1145 AVCodecContext *avctx;
1147 if (stream_index < 0 || stream_index >= ic->nb_streams)
1149 avctx = ic->streams[stream_index]->codec;
1151 switch (avctx->codec_type) {
1152 case AVMEDIA_TYPE_AUDIO:
1153 decoder_abort(&is->auddec, &is->sampq);
1155 decoder_destroy(&is->auddec);
1156 swr_free(&is->swr_ctx);
1157 av_freep(&is->audio_buf1);
1158 is->audio_buf1_size = 0;
1159 is->audio_buf = NULL;
1162 av_rdft_end(is->rdft);
1163 av_freep(&is->rdft_data);
1168 case AVMEDIA_TYPE_VIDEO:
1169 decoder_abort(&is->viddec, &is->pictq);
1170 decoder_destroy(&is->viddec);
1172 case AVMEDIA_TYPE_SUBTITLE:
1173 decoder_abort(&is->subdec, &is->subpq);
1174 decoder_destroy(&is->subdec);
1180 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1181 avcodec_close(avctx);
1182 switch (avctx->codec_type) {
1183 case AVMEDIA_TYPE_AUDIO:
1184 is->audio_st = NULL;
1185 is->audio_stream = -1;
1187 case AVMEDIA_TYPE_VIDEO:
1188 is->video_st = NULL;
1189 is->video_stream = -1;
1191 case AVMEDIA_TYPE_SUBTITLE:
1192 is->subtitle_st = NULL;
1193 is->subtitle_stream = -1;
1200 static void stream_close(VideoState *is)
1202 /* XXX: use a special url_shutdown call to abort parse cleanly */
1203 is->abort_request = 1;
1204 SDL_WaitThread(is->read_tid, NULL);
1206 /* close each stream */
1207 if (is->audio_stream >= 0)
1208 stream_component_close(is, is->audio_stream);
1209 if (is->video_stream >= 0)
1210 stream_component_close(is, is->video_stream);
1211 if (is->subtitle_stream >= 0)
1212 stream_component_close(is, is->subtitle_stream);
1214 avformat_close_input(&is->ic);
1216 packet_queue_destroy(&is->videoq);
1217 packet_queue_destroy(&is->audioq);
1218 packet_queue_destroy(&is->subtitleq);
1220 /* free all pictures */
1221 frame_queue_destory(&is->pictq);
1222 frame_queue_destory(&is->sampq);
1223 frame_queue_destory(&is->subpq);
1224 SDL_DestroyCond(is->continue_read_thread);
1225 #if !CONFIG_AVFILTER
1226 sws_freeContext(is->img_convert_ctx);
1228 sws_freeContext(is->sub_convert_ctx);
1229 av_free(is->filename);
1233 static void do_exit(VideoState *is)
1238 av_lockmgr_register(NULL);
1241 av_freep(&vfilters_list);
1243 avformat_network_deinit();
1247 av_log(NULL, AV_LOG_QUIET, "%s", "");
1251 static void sigterm_handler(int sig)
1256 static void set_default_window_size(int width, int height, AVRational sar)
1259 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1260 default_width = rect.w;
1261 default_height = rect.h;
1264 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1266 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1269 if (is_full_screen) flags |= SDL_FULLSCREEN;
1270 else flags |= SDL_RESIZABLE;
1272 if (vp && vp->width)
1273 set_default_window_size(vp->width, vp->height, vp->sar);
1275 if (is_full_screen && fs_screen_width) {
1276 w = fs_screen_width;
1277 h = fs_screen_height;
1278 } else if (!is_full_screen && screen_width) {
1285 w = FFMIN(16383, w);
1286 if (screen && is->width == screen->w && screen->w == w
1287 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1289 screen = SDL_SetVideoMode(w, h, 0, flags);
1291 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1295 window_title = input_filename;
1296 SDL_WM_SetCaption(window_title, window_title);
1298 is->width = screen->w;
1299 is->height = screen->h;
1304 /* display the current picture, if any */
1305 static void video_display(VideoState *is)
1308 video_open(is, 0, NULL);
1309 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1310 video_audio_display(is);
1311 else if (is->video_st)
1312 video_image_display(is);
1315 static double get_clock(Clock *c)
1317 if (*c->queue_serial != c->serial)
1322 double time = av_gettime_relative() / 1000000.0;
1323 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1327 static void set_clock_at(Clock *c, double pts, int serial, double time)
1330 c->last_updated = time;
1331 c->pts_drift = c->pts - time;
1335 static void set_clock(Clock *c, double pts, int serial)
1337 double time = av_gettime_relative() / 1000000.0;
1338 set_clock_at(c, pts, serial, time);
1341 static void set_clock_speed(Clock *c, double speed)
1343 set_clock(c, get_clock(c), c->serial);
1347 static void init_clock(Clock *c, int *queue_serial)
1351 c->queue_serial = queue_serial;
1352 set_clock(c, NAN, -1);
1355 static void sync_clock_to_slave(Clock *c, Clock *slave)
1357 double clock = get_clock(c);
1358 double slave_clock = get_clock(slave);
1359 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1360 set_clock(c, slave_clock, slave->serial);
1363 static int get_master_sync_type(VideoState *is) {
1364 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1366 return AV_SYNC_VIDEO_MASTER;
1368 return AV_SYNC_AUDIO_MASTER;
1369 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1371 return AV_SYNC_AUDIO_MASTER;
1373 return AV_SYNC_EXTERNAL_CLOCK;
1375 return AV_SYNC_EXTERNAL_CLOCK;
1379 /* get the current master clock value */
1380 static double get_master_clock(VideoState *is)
1384 switch (get_master_sync_type(is)) {
1385 case AV_SYNC_VIDEO_MASTER:
1386 val = get_clock(&is->vidclk);
1388 case AV_SYNC_AUDIO_MASTER:
1389 val = get_clock(&is->audclk);
1392 val = get_clock(&is->extclk);
1398 static void check_external_clock_speed(VideoState *is) {
1399 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1400 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1401 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1402 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1403 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1404 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1406 double speed = is->extclk.speed;
1408 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1412 /* seek in the stream */
1413 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1415 if (!is->seek_req) {
1418 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1420 is->seek_flags |= AVSEEK_FLAG_BYTE;
1422 SDL_CondSignal(is->continue_read_thread);
1426 /* pause or resume the video */
1427 static void stream_toggle_pause(VideoState *is)
1430 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1431 if (is->read_pause_return != AVERROR(ENOSYS)) {
1432 is->vidclk.paused = 0;
1434 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1436 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1437 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1440 static void toggle_pause(VideoState *is)
1442 stream_toggle_pause(is);
1446 static void toggle_mute(VideoState *is)
1448 is->muted = !is->muted;
1451 static void update_volume(VideoState *is, int sign, int step)
1453 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1456 static void step_to_next_frame(VideoState *is)
1458 /* if the stream is paused unpause it, then step */
1460 stream_toggle_pause(is);
1464 static double compute_target_delay(double delay, VideoState *is)
1466 double sync_threshold, diff = 0;
1468 /* update delay to follow master synchronisation source */
1469 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1470 /* if video is slave, we try to correct big delays by
1471 duplicating or deleting a frame */
1472 diff = get_clock(&is->vidclk) - get_master_clock(is);
1474 /* skip or repeat frame. We take into account the
1475 delay to compute the threshold. I still don't know
1476 if it is the best guess */
1477 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1478 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1479 if (diff <= -sync_threshold)
1480 delay = FFMAX(0, delay + diff);
1481 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1482 delay = delay + diff;
1483 else if (diff >= sync_threshold)
1488 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1494 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1495 if (vp->serial == nextvp->serial) {
1496 double duration = nextvp->pts - vp->pts;
1497 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1498 return vp->duration;
1506 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1507 /* update current video pts */
1508 set_clock(&is->vidclk, pts, serial);
1509 sync_clock_to_slave(&is->extclk, &is->vidclk);
1512 /* called to display each frame */
1513 static void video_refresh(void *opaque, double *remaining_time)
1515 VideoState *is = opaque;
1520 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1521 check_external_clock_speed(is);
1523 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1524 time = av_gettime_relative() / 1000000.0;
1525 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1527 is->last_vis_time = time;
1529 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1534 if (is->force_refresh)
1535 redisplay = frame_queue_prev(&is->pictq);
1537 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1538 // nothing to do, no picture to display in the queue
1540 double last_duration, duration, delay;
1543 /* dequeue the picture */
1544 lastvp = frame_queue_peek_last(&is->pictq);
1545 vp = frame_queue_peek(&is->pictq);
1547 if (vp->serial != is->videoq.serial) {
1548 frame_queue_next(&is->pictq);
1553 if (lastvp->serial != vp->serial && !redisplay)
1554 is->frame_timer = av_gettime_relative() / 1000000.0;
1559 /* compute nominal last_duration */
1560 last_duration = vp_duration(is, lastvp, vp);
1564 delay = compute_target_delay(last_duration, is);
1566 time= av_gettime_relative()/1000000.0;
1567 if (time < is->frame_timer + delay && !redisplay) {
1568 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1572 is->frame_timer += delay;
1573 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1574 is->frame_timer = time;
1576 SDL_LockMutex(is->pictq.mutex);
1577 if (!redisplay && !isnan(vp->pts))
1578 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1579 SDL_UnlockMutex(is->pictq.mutex);
1581 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1582 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1583 duration = vp_duration(is, vp, nextvp);
1584 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1586 is->frame_drops_late++;
1587 frame_queue_next(&is->pictq);
1593 if (is->subtitle_st) {
1594 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1595 sp = frame_queue_peek(&is->subpq);
1597 if (frame_queue_nb_remaining(&is->subpq) > 1)
1598 sp2 = frame_queue_peek_next(&is->subpq);
1602 if (sp->serial != is->subtitleq.serial
1603 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1604 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1606 frame_queue_next(&is->subpq);
1614 /* display picture */
1615 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1618 frame_queue_next(&is->pictq);
1620 if (is->step && !is->paused)
1621 stream_toggle_pause(is);
1624 is->force_refresh = 0;
1626 static int64_t last_time;
1628 int aqsize, vqsize, sqsize;
1631 cur_time = av_gettime_relative();
1632 if (!last_time || (cur_time - last_time) >= 30000) {
1637 aqsize = is->audioq.size;
1639 vqsize = is->videoq.size;
1640 if (is->subtitle_st)
1641 sqsize = is->subtitleq.size;
1643 if (is->audio_st && is->video_st)
1644 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1645 else if (is->video_st)
1646 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1647 else if (is->audio_st)
1648 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1649 av_log(NULL, AV_LOG_INFO,
1650 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1651 get_master_clock(is),
1652 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1654 is->frame_drops_early + is->frame_drops_late,
1658 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1659 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1661 last_time = cur_time;
1666 /* allocate a picture (needs to do that in main thread to avoid
1667 potential locking problems */
1668 static void alloc_picture(VideoState *is)
1673 vp = &is->pictq.queue[is->pictq.windex];
1677 video_open(is, 0, vp);
1679 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1682 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1683 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1684 /* SDL allocates a buffer smaller than requested if the video
1685 * overlay hardware is unable to support the requested size. */
1686 av_log(NULL, AV_LOG_FATAL,
1687 "Error: the video system does not support an image\n"
1688 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1689 "to reduce the image size.\n", vp->width, vp->height );
1693 SDL_LockMutex(is->pictq.mutex);
1695 SDL_CondSignal(is->pictq.cond);
1696 SDL_UnlockMutex(is->pictq.mutex);
1699 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1700 int i, width, height;
1702 for (i = 0; i < 3; i++) {
1709 if (bmp->pitches[i] > width) {
1710 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1711 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1717 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1721 #if defined(DEBUG_SYNC) && 0
1722 printf("frame_type=%c pts=%0.3f\n",
1723 av_get_picture_type_char(src_frame->pict_type), pts);
1726 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1729 vp->sar = src_frame->sample_aspect_ratio;
1731 /* alloc or resize hardware picture buffer */
1732 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1733 vp->width != src_frame->width ||
1734 vp->height != src_frame->height) {
1739 vp->width = src_frame->width;
1740 vp->height = src_frame->height;
1742 /* the allocation must be done in the main thread to avoid
1743 locking problems. */
1744 event.type = FF_ALLOC_EVENT;
1745 event.user.data1 = is;
1746 SDL_PushEvent(&event);
1748 /* wait until the picture is allocated */
1749 SDL_LockMutex(is->pictq.mutex);
1750 while (!vp->allocated && !is->videoq.abort_request) {
1751 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1753 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1754 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1755 while (!vp->allocated && !is->abort_request) {
1756 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1759 SDL_UnlockMutex(is->pictq.mutex);
1761 if (is->videoq.abort_request)
1765 /* if the frame is not skipped, then display it */
1767 AVPicture pict = { { 0 } };
1769 /* get a pointer on the bitmap */
1770 SDL_LockYUVOverlay (vp->bmp);
1772 pict.data[0] = vp->bmp->pixels[0];
1773 pict.data[1] = vp->bmp->pixels[2];
1774 pict.data[2] = vp->bmp->pixels[1];
1776 pict.linesize[0] = vp->bmp->pitches[0];
1777 pict.linesize[1] = vp->bmp->pitches[2];
1778 pict.linesize[2] = vp->bmp->pitches[1];
1781 // FIXME use direct rendering
1782 av_picture_copy(&pict, (AVPicture *)src_frame,
1783 src_frame->format, vp->width, vp->height);
1786 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1788 const AVClass *class = sws_get_class();
1789 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1790 AV_OPT_SEARCH_FAKE_OBJ);
1791 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1797 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1798 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1799 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1800 if (!is->img_convert_ctx) {
1801 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1804 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1805 0, vp->height, pict.data, pict.linesize);
1807 /* workaround SDL PITCH_WORKAROUND */
1808 duplicate_right_border_pixels(vp->bmp);
1809 /* update the bitmap content */
1810 SDL_UnlockYUVOverlay(vp->bmp);
1813 vp->duration = duration;
1815 vp->serial = serial;
1817 /* now we can update the picture count */
1818 frame_queue_push(&is->pictq);
1823 static int get_video_frame(VideoState *is, AVFrame *frame)
1827 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1833 if (frame->pts != AV_NOPTS_VALUE)
1834 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1836 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1838 is->viddec_width = frame->width;
1839 is->viddec_height = frame->height;
1841 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1842 if (frame->pts != AV_NOPTS_VALUE) {
1843 double diff = dpts - get_master_clock(is);
1844 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1845 diff - is->frame_last_filter_delay < 0 &&
1846 is->viddec.pkt_serial == is->vidclk.serial &&
1847 is->videoq.nb_packets) {
1848 is->frame_drops_early++;
1849 av_frame_unref(frame);
1860 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1861 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1864 int nb_filters = graph->nb_filters;
1865 AVFilterInOut *outputs = NULL, *inputs = NULL;
1868 outputs = avfilter_inout_alloc();
1869 inputs = avfilter_inout_alloc();
1870 if (!outputs || !inputs) {
1871 ret = AVERROR(ENOMEM);
1875 outputs->name = av_strdup("in");
1876 outputs->filter_ctx = source_ctx;
1877 outputs->pad_idx = 0;
1878 outputs->next = NULL;
1880 inputs->name = av_strdup("out");
1881 inputs->filter_ctx = sink_ctx;
1882 inputs->pad_idx = 0;
1883 inputs->next = NULL;
1885 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1888 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1892 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1893 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1894 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1896 ret = avfilter_graph_config(graph, NULL);
1898 avfilter_inout_free(&outputs);
1899 avfilter_inout_free(&inputs);
1903 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1905 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1906 char sws_flags_str[512] = "";
1907 char buffersrc_args[256];
1909 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1910 AVCodecContext *codec = is->video_st->codec;
1911 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1912 AVDictionaryEntry *e = NULL;
1914 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1915 if (!strcmp(e->key, "sws_flags")) {
1916 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1918 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1920 if (strlen(sws_flags_str))
1921 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1923 graph->scale_sws_opts = av_strdup(sws_flags_str);
1925 snprintf(buffersrc_args, sizeof(buffersrc_args),
1926 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1927 frame->width, frame->height, frame->format,
1928 is->video_st->time_base.num, is->video_st->time_base.den,
1929 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1930 if (fr.num && fr.den)
1931 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1933 if ((ret = avfilter_graph_create_filter(&filt_src,
1934 avfilter_get_by_name("buffer"),
1935 "ffplay_buffer", buffersrc_args, NULL,
1939 ret = avfilter_graph_create_filter(&filt_out,
1940 avfilter_get_by_name("buffersink"),
1941 "ffplay_buffersink", NULL, NULL, graph);
1945 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1948 last_filter = filt_out;
1950 /* Note: this macro adds a filter before the lastly added filter, so the
1951 * processing order of the filters is in reverse */
1952 #define INSERT_FILT(name, arg) do { \
1953 AVFilterContext *filt_ctx; \
1955 ret = avfilter_graph_create_filter(&filt_ctx, \
1956 avfilter_get_by_name(name), \
1957 "ffplay_" name, arg, NULL, graph); \
1961 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1965 last_filter = filt_ctx; \
1968 /* SDL YUV code is not handling odd width/height for some driver
1969 * combinations, therefore we crop the picture to an even width/height. */
1970 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1973 double theta = get_rotation(is->video_st);
1975 if (fabs(theta - 90) < 1.0) {
1976 INSERT_FILT("transpose", "clock");
1977 } else if (fabs(theta - 180) < 1.0) {
1978 INSERT_FILT("hflip", NULL);
1979 INSERT_FILT("vflip", NULL);
1980 } else if (fabs(theta - 270) < 1.0) {
1981 INSERT_FILT("transpose", "cclock");
1982 } else if (fabs(theta) > 1.0) {
1983 char rotate_buf[64];
1984 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1985 INSERT_FILT("rotate", rotate_buf);
1989 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1992 is->in_video_filter = filt_src;
1993 is->out_video_filter = filt_out;
1999 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
2001 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2002 int sample_rates[2] = { 0, -1 };
2003 int64_t channel_layouts[2] = { 0, -1 };
2004 int channels[2] = { 0, -1 };
2005 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2006 char aresample_swr_opts[512] = "";
2007 AVDictionaryEntry *e = NULL;
2008 char asrc_args[256];
2011 avfilter_graph_free(&is->agraph);
2012 if (!(is->agraph = avfilter_graph_alloc()))
2013 return AVERROR(ENOMEM);
2015 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2016 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2017 if (strlen(aresample_swr_opts))
2018 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2019 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2021 ret = snprintf(asrc_args, sizeof(asrc_args),
2022 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2023 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2024 is->audio_filter_src.channels,
2025 1, is->audio_filter_src.freq);
2026 if (is->audio_filter_src.channel_layout)
2027 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2028 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2030 ret = avfilter_graph_create_filter(&filt_asrc,
2031 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2032 asrc_args, NULL, is->agraph);
2037 ret = avfilter_graph_create_filter(&filt_asink,
2038 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2039 NULL, NULL, is->agraph);
2043 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2045 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2048 if (force_output_format) {
2049 channel_layouts[0] = is->audio_tgt.channel_layout;
2050 channels [0] = is->audio_tgt.channels;
2051 sample_rates [0] = is->audio_tgt.freq;
2052 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2054 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2056 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2058 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2063 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2066 is->in_audio_filter = filt_asrc;
2067 is->out_audio_filter = filt_asink;
2071 avfilter_graph_free(&is->agraph);
2074 #endif /* CONFIG_AVFILTER */
2076 static int audio_thread(void *arg)
2078 VideoState *is = arg;
2079 AVFrame *frame = av_frame_alloc();
2082 int last_serial = -1;
2083 int64_t dec_channel_layout;
2091 return AVERROR(ENOMEM);
2094 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2098 tb = (AVRational){1, frame->sample_rate};
2101 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2104 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2105 frame->format, av_frame_get_channels(frame)) ||
2106 is->audio_filter_src.channel_layout != dec_channel_layout ||
2107 is->audio_filter_src.freq != frame->sample_rate ||
2108 is->auddec.pkt_serial != last_serial;
2111 char buf1[1024], buf2[1024];
2112 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2113 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2114 av_log(NULL, AV_LOG_DEBUG,
2115 "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",
2116 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2117 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2119 is->audio_filter_src.fmt = frame->format;
2120 is->audio_filter_src.channels = av_frame_get_channels(frame);
2121 is->audio_filter_src.channel_layout = dec_channel_layout;
2122 is->audio_filter_src.freq = frame->sample_rate;
2123 last_serial = is->auddec.pkt_serial;
2125 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2129 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2132 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2133 tb = is->out_audio_filter->inputs[0]->time_base;
2135 if (!(af = frame_queue_peek_writable(&is->sampq)))
2138 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2139 af->pos = av_frame_get_pkt_pos(frame);
2140 af->serial = is->auddec.pkt_serial;
2141 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2143 av_frame_move_ref(af->frame, frame);
2144 frame_queue_push(&is->sampq);
2147 if (is->audioq.serial != is->auddec.pkt_serial)
2150 if (ret == AVERROR_EOF)
2151 is->auddec.finished = is->auddec.pkt_serial;
2154 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2157 avfilter_graph_free(&is->agraph);
2159 av_frame_free(&frame);
2163 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2165 packet_queue_start(d->queue);
2166 d->decoder_tid = SDL_CreateThread(fn, arg);
2167 if (!d->decoder_tid) {
2168 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2169 return AVERROR(ENOMEM);
2174 static int video_thread(void *arg)
2176 VideoState *is = arg;
2177 AVFrame *frame = av_frame_alloc();
2181 AVRational tb = is->video_st->time_base;
2182 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2185 AVFilterGraph *graph = avfilter_graph_alloc();
2186 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2189 enum AVPixelFormat last_format = -2;
2190 int last_serial = -1;
2191 int last_vfilter_idx = 0;
2193 av_frame_free(&frame);
2194 return AVERROR(ENOMEM);
2201 avfilter_graph_free(&graph);
2203 return AVERROR(ENOMEM);
2207 ret = get_video_frame(is, frame);
2214 if ( last_w != frame->width
2215 || last_h != frame->height
2216 || last_format != frame->format
2217 || last_serial != is->viddec.pkt_serial
2218 || last_vfilter_idx != is->vfilter_idx) {
2219 av_log(NULL, AV_LOG_DEBUG,
2220 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2222 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2223 frame->width, frame->height,
2224 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2225 avfilter_graph_free(&graph);
2226 graph = avfilter_graph_alloc();
2227 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2229 event.type = FF_QUIT_EVENT;
2230 event.user.data1 = is;
2231 SDL_PushEvent(&event);
2234 filt_in = is->in_video_filter;
2235 filt_out = is->out_video_filter;
2236 last_w = frame->width;
2237 last_h = frame->height;
2238 last_format = frame->format;
2239 last_serial = is->viddec.pkt_serial;
2240 last_vfilter_idx = is->vfilter_idx;
2241 frame_rate = filt_out->inputs[0]->frame_rate;
2244 ret = av_buffersrc_add_frame(filt_in, frame);
2249 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2251 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2253 if (ret == AVERROR_EOF)
2254 is->viddec.finished = is->viddec.pkt_serial;
2259 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2260 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2261 is->frame_last_filter_delay = 0;
2262 tb = filt_out->inputs[0]->time_base;
2264 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2265 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2266 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2267 av_frame_unref(frame);
2277 avfilter_graph_free(&graph);
2279 av_frame_free(&frame);
2283 static int subtitle_thread(void *arg)
2285 VideoState *is = arg;
2292 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2295 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2300 if (got_subtitle && sp->sub.format == 0) {
2301 if (sp->sub.pts != AV_NOPTS_VALUE)
2302 pts = sp->sub.pts / (double)AV_TIME_BASE;
2304 sp->serial = is->subdec.pkt_serial;
2305 if (!(sp->subrects = av_mallocz_array(sp->sub.num_rects, sizeof(AVSubtitleRect*)))) {
2306 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subrects\n");
2310 for (i = 0; i < sp->sub.num_rects; i++)
2312 int in_w = sp->sub.rects[i]->w;
2313 int in_h = sp->sub.rects[i]->h;
2314 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2315 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2316 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2317 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2319 if (!(sp->subrects[i] = av_mallocz(sizeof(AVSubtitleRect))) ||
2320 av_image_alloc(sp->subrects[i]->data, sp->subrects[i]->linesize, out_w, out_h, AV_PIX_FMT_YUVA420P, 16) < 0) {
2321 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subtitle data\n");
2325 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2326 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2327 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2328 if (!is->sub_convert_ctx) {
2329 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2332 sws_scale(is->sub_convert_ctx,
2333 (void*)sp->sub.rects[i]->data, sp->sub.rects[i]->linesize,
2334 0, in_h, sp->subrects[i]->data, sp->subrects[i]->linesize);
2336 sp->subrects[i]->w = out_w;
2337 sp->subrects[i]->h = out_h;
2338 sp->subrects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2339 sp->subrects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2342 /* now we can update the picture count */
2343 frame_queue_push(&is->subpq);
2344 } else if (got_subtitle) {
2345 avsubtitle_free(&sp->sub);
2351 /* copy samples for viewing in editor window */
2352 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2356 size = samples_size / sizeof(short);
2358 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2361 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2363 is->sample_array_index += len;
2364 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2365 is->sample_array_index = 0;
2370 /* return the wanted number of samples to get better sync if sync_type is video
2371 * or external master clock */
2372 static int synchronize_audio(VideoState *is, int nb_samples)
2374 int wanted_nb_samples = nb_samples;
2376 /* if not master, then we try to remove or add samples to correct the clock */
2377 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2378 double diff, avg_diff;
2379 int min_nb_samples, max_nb_samples;
2381 diff = get_clock(&is->audclk) - get_master_clock(is);
2383 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2384 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2385 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2386 /* not enough measures to have a correct estimate */
2387 is->audio_diff_avg_count++;
2389 /* estimate the A-V difference */
2390 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2392 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2393 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2394 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2395 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2396 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2398 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2399 diff, avg_diff, wanted_nb_samples - nb_samples,
2400 is->audio_clock, is->audio_diff_threshold);
2403 /* too big difference : may be initial PTS errors, so
2405 is->audio_diff_avg_count = 0;
2406 is->audio_diff_cum = 0;
2410 return wanted_nb_samples;
2414 * Decode one audio frame and return its uncompressed size.
2416 * The processed audio frame is decoded, converted if required, and
2417 * stored in is->audio_buf, with size in bytes given by the return
2420 static int audio_decode_frame(VideoState *is)
2422 int data_size, resampled_data_size;
2423 int64_t dec_channel_layout;
2424 av_unused double audio_clock0;
2425 int wanted_nb_samples;
2433 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2434 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2439 if (!(af = frame_queue_peek_readable(&is->sampq)))
2441 frame_queue_next(&is->sampq);
2442 } while (af->serial != is->audioq.serial);
2444 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2445 af->frame->nb_samples,
2446 af->frame->format, 1);
2448 dec_channel_layout =
2449 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2450 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2451 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2453 if (af->frame->format != is->audio_src.fmt ||
2454 dec_channel_layout != is->audio_src.channel_layout ||
2455 af->frame->sample_rate != is->audio_src.freq ||
2456 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2457 swr_free(&is->swr_ctx);
2458 is->swr_ctx = swr_alloc_set_opts(NULL,
2459 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2460 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2462 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2463 av_log(NULL, AV_LOG_ERROR,
2464 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2465 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2466 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2467 swr_free(&is->swr_ctx);
2470 is->audio_src.channel_layout = dec_channel_layout;
2471 is->audio_src.channels = av_frame_get_channels(af->frame);
2472 is->audio_src.freq = af->frame->sample_rate;
2473 is->audio_src.fmt = af->frame->format;
2477 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2478 uint8_t **out = &is->audio_buf1;
2479 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2480 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2483 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2486 if (wanted_nb_samples != af->frame->nb_samples) {
2487 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2488 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2489 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2493 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2494 if (!is->audio_buf1)
2495 return AVERROR(ENOMEM);
2496 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2498 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2501 if (len2 == out_count) {
2502 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2503 if (swr_init(is->swr_ctx) < 0)
2504 swr_free(&is->swr_ctx);
2506 is->audio_buf = is->audio_buf1;
2507 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2509 is->audio_buf = af->frame->data[0];
2510 resampled_data_size = data_size;
2513 audio_clock0 = is->audio_clock;
2514 /* update the audio clock with the pts */
2515 if (!isnan(af->pts))
2516 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2518 is->audio_clock = NAN;
2519 is->audio_clock_serial = af->serial;
2522 static double last_clock;
2523 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2524 is->audio_clock - last_clock,
2525 is->audio_clock, audio_clock0);
2526 last_clock = is->audio_clock;
2529 return resampled_data_size;
2532 /* prepare a new audio buffer */
2533 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2535 VideoState *is = opaque;
2536 int audio_size, len1;
2538 audio_callback_time = av_gettime_relative();
2541 if (is->audio_buf_index >= is->audio_buf_size) {
2542 audio_size = audio_decode_frame(is);
2543 if (audio_size < 0) {
2544 /* if error, just output silence */
2545 is->audio_buf = is->silence_buf;
2546 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2548 if (is->show_mode != SHOW_MODE_VIDEO)
2549 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2550 is->audio_buf_size = audio_size;
2552 is->audio_buf_index = 0;
2554 len1 = is->audio_buf_size - is->audio_buf_index;
2557 if (!is->muted && is->audio_volume == SDL_MIX_MAXVOLUME)
2558 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2560 memset(stream, is->silence_buf[0], len1);
2562 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2566 is->audio_buf_index += len1;
2568 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2569 /* Let's assume the audio driver that is used by SDL has two periods. */
2570 if (!isnan(is->audio_clock)) {
2571 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);
2572 sync_clock_to_slave(&is->extclk, &is->audclk);
2576 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2578 SDL_AudioSpec wanted_spec, spec;
2580 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2581 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2582 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2584 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2586 wanted_nb_channels = atoi(env);
2587 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2589 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2590 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2591 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2593 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2594 wanted_spec.channels = wanted_nb_channels;
2595 wanted_spec.freq = wanted_sample_rate;
2596 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2597 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2600 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2601 next_sample_rate_idx--;
2602 wanted_spec.format = AUDIO_S16SYS;
2603 wanted_spec.silence = 0;
2604 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2605 wanted_spec.callback = sdl_audio_callback;
2606 wanted_spec.userdata = opaque;
2607 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2608 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2609 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2610 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2611 if (!wanted_spec.channels) {
2612 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2613 wanted_spec.channels = wanted_nb_channels;
2614 if (!wanted_spec.freq) {
2615 av_log(NULL, AV_LOG_ERROR,
2616 "No more combinations to try, audio open failed\n");
2620 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2622 if (spec.format != AUDIO_S16SYS) {
2623 av_log(NULL, AV_LOG_ERROR,
2624 "SDL advised audio format %d is not supported!\n", spec.format);
2627 if (spec.channels != wanted_spec.channels) {
2628 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2629 if (!wanted_channel_layout) {
2630 av_log(NULL, AV_LOG_ERROR,
2631 "SDL advised channel count %d is not supported!\n", spec.channels);
2636 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2637 audio_hw_params->freq = spec.freq;
2638 audio_hw_params->channel_layout = wanted_channel_layout;
2639 audio_hw_params->channels = spec.channels;
2640 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2641 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);
2642 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2643 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2649 /* open a given stream. Return 0 if OK */
2650 static int stream_component_open(VideoState *is, int stream_index)
2652 AVFormatContext *ic = is->ic;
2653 AVCodecContext *avctx;
2655 const char *forced_codec_name = NULL;
2657 AVDictionaryEntry *t = NULL;
2658 int sample_rate, nb_channels;
2659 int64_t channel_layout;
2661 int stream_lowres = lowres;
2663 if (stream_index < 0 || stream_index >= ic->nb_streams)
2665 avctx = ic->streams[stream_index]->codec;
2667 codec = avcodec_find_decoder(avctx->codec_id);
2669 switch(avctx->codec_type){
2670 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2671 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2672 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2674 if (forced_codec_name)
2675 codec = avcodec_find_decoder_by_name(forced_codec_name);
2677 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2678 "No codec could be found with name '%s'\n", forced_codec_name);
2679 else av_log(NULL, AV_LOG_WARNING,
2680 "No codec could be found with id %d\n", avctx->codec_id);
2684 avctx->codec_id = codec->id;
2685 if(stream_lowres > av_codec_get_max_lowres(codec)){
2686 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2687 av_codec_get_max_lowres(codec));
2688 stream_lowres = av_codec_get_max_lowres(codec);
2690 av_codec_set_lowres(avctx, stream_lowres);
2693 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2696 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2698 if(codec->capabilities & AV_CODEC_CAP_DR1)
2699 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2702 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2703 if (!av_dict_get(opts, "threads", NULL, 0))
2704 av_dict_set(&opts, "threads", "auto", 0);
2706 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2707 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2708 av_dict_set(&opts, "refcounted_frames", "1", 0);
2709 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2712 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2713 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2714 ret = AVERROR_OPTION_NOT_FOUND;
2719 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2720 switch (avctx->codec_type) {
2721 case AVMEDIA_TYPE_AUDIO:
2726 is->audio_filter_src.freq = avctx->sample_rate;
2727 is->audio_filter_src.channels = avctx->channels;
2728 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2729 is->audio_filter_src.fmt = avctx->sample_fmt;
2730 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2732 link = is->out_audio_filter->inputs[0];
2733 sample_rate = link->sample_rate;
2734 nb_channels = link->channels;
2735 channel_layout = link->channel_layout;
2738 sample_rate = avctx->sample_rate;
2739 nb_channels = avctx->channels;
2740 channel_layout = avctx->channel_layout;
2743 /* prepare audio output */
2744 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2746 is->audio_hw_buf_size = ret;
2747 is->audio_src = is->audio_tgt;
2748 is->audio_buf_size = 0;
2749 is->audio_buf_index = 0;
2751 /* init averaging filter */
2752 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2753 is->audio_diff_avg_count = 0;
2754 /* since we do not have a precise anough audio fifo fullness,
2755 we correct audio sync only if larger than this threshold */
2756 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2758 is->audio_stream = stream_index;
2759 is->audio_st = ic->streams[stream_index];
2761 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2762 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2763 is->auddec.start_pts = is->audio_st->start_time;
2764 is->auddec.start_pts_tb = is->audio_st->time_base;
2766 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2770 case AVMEDIA_TYPE_VIDEO:
2771 is->video_stream = stream_index;
2772 is->video_st = ic->streams[stream_index];
2774 is->viddec_width = avctx->width;
2775 is->viddec_height = avctx->height;
2777 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2778 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2780 is->queue_attachments_req = 1;
2782 case AVMEDIA_TYPE_SUBTITLE:
2783 is->subtitle_stream = stream_index;
2784 is->subtitle_st = ic->streams[stream_index];
2786 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2787 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2795 av_dict_free(&opts);
2800 static int decode_interrupt_cb(void *ctx)
2802 VideoState *is = ctx;
2803 return is->abort_request;
2806 static int is_realtime(AVFormatContext *s)
2808 if( !strcmp(s->iformat->name, "rtp")
2809 || !strcmp(s->iformat->name, "rtsp")
2810 || !strcmp(s->iformat->name, "sdp")
2814 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2815 || !strncmp(s->filename, "udp:", 4)
2822 /* this thread gets the stream from the disk or the network */
2823 static int read_thread(void *arg)
2825 VideoState *is = arg;
2826 AVFormatContext *ic = NULL;
2828 int st_index[AVMEDIA_TYPE_NB];
2829 AVPacket pkt1, *pkt = &pkt1;
2830 int64_t stream_start_time;
2831 int pkt_in_play_range = 0;
2832 AVDictionaryEntry *t;
2833 AVDictionary **opts;
2834 int orig_nb_streams;
2835 SDL_mutex *wait_mutex = SDL_CreateMutex();
2836 int scan_all_pmts_set = 0;
2840 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2841 ret = AVERROR(ENOMEM);
2845 memset(st_index, -1, sizeof(st_index));
2846 is->last_video_stream = is->video_stream = -1;
2847 is->last_audio_stream = is->audio_stream = -1;
2848 is->last_subtitle_stream = is->subtitle_stream = -1;
2851 ic = avformat_alloc_context();
2853 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2854 ret = AVERROR(ENOMEM);
2857 ic->interrupt_callback.callback = decode_interrupt_cb;
2858 ic->interrupt_callback.opaque = is;
2859 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2860 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2861 scan_all_pmts_set = 1;
2863 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2865 print_error(is->filename, err);
2869 if (scan_all_pmts_set)
2870 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2872 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2873 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2874 ret = AVERROR_OPTION_NOT_FOUND;
2880 ic->flags |= AVFMT_FLAG_GENPTS;
2882 av_format_inject_global_side_data(ic);
2884 opts = setup_find_stream_info_opts(ic, codec_opts);
2885 orig_nb_streams = ic->nb_streams;
2887 err = avformat_find_stream_info(ic, opts);
2889 for (i = 0; i < orig_nb_streams; i++)
2890 av_dict_free(&opts[i]);
2894 av_log(NULL, AV_LOG_WARNING,
2895 "%s: could not find codec parameters\n", is->filename);
2901 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2903 if (seek_by_bytes < 0)
2904 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2906 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2908 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2909 window_title = av_asprintf("%s - %s", t->value, input_filename);
2911 /* if seeking requested, we execute it */
2912 if (start_time != AV_NOPTS_VALUE) {
2915 timestamp = start_time;
2916 /* add the stream start time */
2917 if (ic->start_time != AV_NOPTS_VALUE)
2918 timestamp += ic->start_time;
2919 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2921 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2922 is->filename, (double)timestamp / AV_TIME_BASE);
2926 is->realtime = is_realtime(ic);
2929 av_dump_format(ic, 0, is->filename, 0);
2931 for (i = 0; i < ic->nb_streams; i++) {
2932 AVStream *st = ic->streams[i];
2933 enum AVMediaType type = st->codec->codec_type;
2934 st->discard = AVDISCARD_ALL;
2935 if (wanted_stream_spec[type] && st_index[type] == -1)
2936 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2939 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2940 if (wanted_stream_spec[i] && st_index[i] == -1) {
2941 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));
2942 st_index[i] = INT_MAX;
2947 st_index[AVMEDIA_TYPE_VIDEO] =
2948 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2949 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2951 st_index[AVMEDIA_TYPE_AUDIO] =
2952 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2953 st_index[AVMEDIA_TYPE_AUDIO],
2954 st_index[AVMEDIA_TYPE_VIDEO],
2956 if (!video_disable && !subtitle_disable)
2957 st_index[AVMEDIA_TYPE_SUBTITLE] =
2958 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2959 st_index[AVMEDIA_TYPE_SUBTITLE],
2960 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2961 st_index[AVMEDIA_TYPE_AUDIO] :
2962 st_index[AVMEDIA_TYPE_VIDEO]),
2965 is->show_mode = show_mode;
2966 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2967 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2968 AVCodecContext *avctx = st->codec;
2969 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2971 set_default_window_size(avctx->width, avctx->height, sar);
2974 /* open the streams */
2975 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2976 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2980 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2981 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2983 if (is->show_mode == SHOW_MODE_NONE)
2984 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2986 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2987 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2990 if (is->video_stream < 0 && is->audio_stream < 0) {
2991 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2997 if (infinite_buffer < 0 && is->realtime)
2998 infinite_buffer = 1;
3001 if (is->abort_request)
3003 if (is->paused != is->last_paused) {
3004 is->last_paused = is->paused;
3006 is->read_pause_return = av_read_pause(ic);
3010 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3012 (!strcmp(ic->iformat->name, "rtsp") ||
3013 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3014 /* wait 10 ms to avoid trying to get another packet */
3021 int64_t seek_target = is->seek_pos;
3022 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3023 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3024 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3025 // of the seek_pos/seek_rel variables
3027 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3029 av_log(NULL, AV_LOG_ERROR,
3030 "%s: error while seeking\n", is->ic->filename);
3032 if (is->audio_stream >= 0) {
3033 packet_queue_flush(&is->audioq);
3034 packet_queue_put(&is->audioq, &flush_pkt);
3036 if (is->subtitle_stream >= 0) {
3037 packet_queue_flush(&is->subtitleq);
3038 packet_queue_put(&is->subtitleq, &flush_pkt);
3040 if (is->video_stream >= 0) {
3041 packet_queue_flush(&is->videoq);
3042 packet_queue_put(&is->videoq, &flush_pkt);
3044 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3045 set_clock(&is->extclk, NAN, 0);
3047 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3051 is->queue_attachments_req = 1;
3054 step_to_next_frame(is);
3056 if (is->queue_attachments_req) {
3057 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3059 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3061 packet_queue_put(&is->videoq, ©);
3062 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3064 is->queue_attachments_req = 0;
3067 /* if the queue are full, no need to read more */
3068 if (infinite_buffer<1 &&
3069 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3070 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3071 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3072 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3073 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3075 SDL_LockMutex(wait_mutex);
3076 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3077 SDL_UnlockMutex(wait_mutex);
3081 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3082 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3083 if (loop != 1 && (!loop || --loop)) {
3084 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3085 } else if (autoexit) {
3090 ret = av_read_frame(ic, pkt);
3092 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3093 if (is->video_stream >= 0)
3094 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3095 if (is->audio_stream >= 0)
3096 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3097 if (is->subtitle_stream >= 0)
3098 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3101 if (ic->pb && ic->pb->error)
3103 SDL_LockMutex(wait_mutex);
3104 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3105 SDL_UnlockMutex(wait_mutex);
3110 /* check if packet is in play range specified by user, then queue, otherwise discard */
3111 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3112 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3113 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3114 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3115 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3116 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3117 <= ((double)duration / 1000000);
3118 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3119 packet_queue_put(&is->audioq, pkt);
3120 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3121 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3122 packet_queue_put(&is->videoq, pkt);
3123 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3124 packet_queue_put(&is->subtitleq, pkt);
3126 av_free_packet(pkt);
3133 avformat_close_input(&ic);
3138 event.type = FF_QUIT_EVENT;
3139 event.user.data1 = is;
3140 SDL_PushEvent(&event);
3142 SDL_DestroyMutex(wait_mutex);
3146 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3150 is = av_mallocz(sizeof(VideoState));
3153 is->filename = av_strdup(filename);
3156 is->iformat = iformat;
3160 /* start video display */
3161 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3163 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3165 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3168 if (packet_queue_init(&is->videoq) < 0 ||
3169 packet_queue_init(&is->audioq) < 0 ||
3170 packet_queue_init(&is->subtitleq) < 0)
3173 if (!(is->continue_read_thread = SDL_CreateCond())) {
3174 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3178 init_clock(&is->vidclk, &is->videoq.serial);
3179 init_clock(&is->audclk, &is->audioq.serial);
3180 init_clock(&is->extclk, &is->extclk.serial);
3181 is->audio_clock_serial = -1;
3182 is->audio_volume = SDL_MIX_MAXVOLUME;
3184 is->av_sync_type = av_sync_type;
3185 is->read_tid = SDL_CreateThread(read_thread, is);
3186 if (!is->read_tid) {
3187 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3195 static void stream_cycle_channel(VideoState *is, int codec_type)
3197 AVFormatContext *ic = is->ic;
3198 int start_index, stream_index;
3201 AVProgram *p = NULL;
3202 int nb_streams = is->ic->nb_streams;
3204 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3205 start_index = is->last_video_stream;
3206 old_index = is->video_stream;
3207 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3208 start_index = is->last_audio_stream;
3209 old_index = is->audio_stream;
3211 start_index = is->last_subtitle_stream;
3212 old_index = is->subtitle_stream;
3214 stream_index = start_index;
3216 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3217 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3219 nb_streams = p->nb_stream_indexes;
3220 for (start_index = 0; start_index < nb_streams; start_index++)
3221 if (p->stream_index[start_index] == stream_index)
3223 if (start_index == nb_streams)
3225 stream_index = start_index;
3230 if (++stream_index >= nb_streams)
3232 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3235 is->last_subtitle_stream = -1;
3238 if (start_index == -1)
3242 if (stream_index == start_index)
3244 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3245 if (st->codec->codec_type == codec_type) {
3246 /* check that parameters are OK */
3247 switch (codec_type) {
3248 case AVMEDIA_TYPE_AUDIO:
3249 if (st->codec->sample_rate != 0 &&
3250 st->codec->channels != 0)
3253 case AVMEDIA_TYPE_VIDEO:
3254 case AVMEDIA_TYPE_SUBTITLE:
3262 if (p && stream_index != -1)
3263 stream_index = p->stream_index[stream_index];
3264 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3265 av_get_media_type_string(codec_type),
3269 stream_component_close(is, old_index);
3270 stream_component_open(is, stream_index);
3274 static void toggle_full_screen(VideoState *is)
3276 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3277 /* OS X needs to reallocate the SDL overlays */
3279 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3280 is->pictq.queue[i].reallocate = 1;
3282 is_full_screen = !is_full_screen;
3283 video_open(is, 1, NULL);
3286 static void toggle_audio_display(VideoState *is)
3288 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3289 int next = is->show_mode;
3291 next = (next + 1) % SHOW_MODE_NB;
3292 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3293 if (is->show_mode != next) {
3294 fill_rectangle(screen,
3295 is->xleft, is->ytop, is->width, is->height,
3297 is->force_refresh = 1;
3298 is->show_mode = next;
3302 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3303 double remaining_time = 0.0;
3305 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3306 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3310 if (remaining_time > 0.0)
3311 av_usleep((int64_t)(remaining_time * 1000000.0));
3312 remaining_time = REFRESH_RATE;
3313 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3314 video_refresh(is, &remaining_time);
3319 static void seek_chapter(VideoState *is, int incr)
3321 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3324 if (!is->ic->nb_chapters)
3327 /* find the current chapter */
3328 for (i = 0; i < is->ic->nb_chapters; i++) {
3329 AVChapter *ch = is->ic->chapters[i];
3330 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3338 if (i >= is->ic->nb_chapters)
3341 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3342 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3343 AV_TIME_BASE_Q), 0, 0);
3346 /* handle an event sent by the GUI */
3347 static void event_loop(VideoState *cur_stream)
3350 double incr, pos, frac;
3354 refresh_loop_wait_event(cur_stream, &event);
3355 switch (event.type) {
3357 if (exit_on_keydown) {
3358 do_exit(cur_stream);
3361 switch (event.key.keysym.sym) {
3364 do_exit(cur_stream);
3367 toggle_full_screen(cur_stream);
3368 cur_stream->force_refresh = 1;
3372 toggle_pause(cur_stream);
3375 toggle_mute(cur_stream);
3377 case SDLK_KP_MULTIPLY:
3379 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3381 case SDLK_KP_DIVIDE:
3383 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3385 case SDLK_s: // S: Step to next frame
3386 step_to_next_frame(cur_stream);
3389 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3392 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3395 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3396 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3397 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3400 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3404 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3405 if (++cur_stream->vfilter_idx >= nb_vfilters)
3406 cur_stream->vfilter_idx = 0;
3408 cur_stream->vfilter_idx = 0;
3409 toggle_audio_display(cur_stream);
3412 toggle_audio_display(cur_stream);
3416 if (cur_stream->ic->nb_chapters <= 1) {
3420 seek_chapter(cur_stream, 1);
3423 if (cur_stream->ic->nb_chapters <= 1) {
3427 seek_chapter(cur_stream, -1);
3441 if (seek_by_bytes) {
3443 if (pos < 0 && cur_stream->video_stream >= 0)
3444 pos = frame_queue_last_pos(&cur_stream->pictq);
3445 if (pos < 0 && cur_stream->audio_stream >= 0)
3446 pos = frame_queue_last_pos(&cur_stream->sampq);
3448 pos = avio_tell(cur_stream->ic->pb);
3449 if (cur_stream->ic->bit_rate)
3450 incr *= cur_stream->ic->bit_rate / 8.0;
3454 stream_seek(cur_stream, pos, incr, 1);
3456 pos = get_master_clock(cur_stream);
3458 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3460 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3461 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3462 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3469 case SDL_VIDEOEXPOSE:
3470 cur_stream->force_refresh = 1;
3472 case SDL_MOUSEBUTTONDOWN:
3473 if (exit_on_mousedown) {
3474 do_exit(cur_stream);
3477 case SDL_MOUSEMOTION:
3478 if (cursor_hidden) {
3482 cursor_last_shown = av_gettime_relative();
3483 if (event.type == SDL_MOUSEBUTTONDOWN) {
3486 if (event.motion.state != SDL_PRESSED)
3490 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3491 uint64_t size = avio_size(cur_stream->ic->pb);
3492 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3496 int tns, thh, tmm, tss;
3497 tns = cur_stream->ic->duration / 1000000LL;
3499 tmm = (tns % 3600) / 60;
3501 frac = x / cur_stream->width;
3504 mm = (ns % 3600) / 60;
3506 av_log(NULL, AV_LOG_INFO,
3507 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3508 hh, mm, ss, thh, tmm, tss);
3509 ts = frac * cur_stream->ic->duration;
3510 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3511 ts += cur_stream->ic->start_time;
3512 stream_seek(cur_stream, ts, 0, 0);
3515 case SDL_VIDEORESIZE:
3516 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3517 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3519 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3520 do_exit(cur_stream);
3522 screen_width = cur_stream->width = screen->w;
3523 screen_height = cur_stream->height = screen->h;
3524 cur_stream->force_refresh = 1;
3528 do_exit(cur_stream);
3530 case FF_ALLOC_EVENT:
3531 alloc_picture(event.user.data1);
3539 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3541 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3542 return opt_default(NULL, "video_size", arg);
3545 static int opt_width(void *optctx, const char *opt, const char *arg)
3547 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3551 static int opt_height(void *optctx, const char *opt, const char *arg)
3553 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3557 static int opt_format(void *optctx, const char *opt, const char *arg)
3559 file_iformat = av_find_input_format(arg);
3560 if (!file_iformat) {
3561 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3562 return AVERROR(EINVAL);
3567 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3569 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3570 return opt_default(NULL, "pixel_format", arg);
3573 static int opt_sync(void *optctx, const char *opt, const char *arg)
3575 if (!strcmp(arg, "audio"))
3576 av_sync_type = AV_SYNC_AUDIO_MASTER;
3577 else if (!strcmp(arg, "video"))
3578 av_sync_type = AV_SYNC_VIDEO_MASTER;
3579 else if (!strcmp(arg, "ext"))
3580 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3582 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3588 static int opt_seek(void *optctx, const char *opt, const char *arg)
3590 start_time = parse_time_or_die(opt, arg, 1);
3594 static int opt_duration(void *optctx, const char *opt, const char *arg)
3596 duration = parse_time_or_die(opt, arg, 1);
3600 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3602 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3603 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3604 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3605 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3609 static void opt_input_file(void *optctx, const char *filename)
3611 if (input_filename) {
3612 av_log(NULL, AV_LOG_FATAL,
3613 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3614 filename, input_filename);
3617 if (!strcmp(filename, "-"))
3619 input_filename = filename;
3622 static int opt_codec(void *optctx, const char *opt, const char *arg)
3624 const char *spec = strchr(opt, ':');
3626 av_log(NULL, AV_LOG_ERROR,
3627 "No media specifier was specified in '%s' in option '%s'\n",
3629 return AVERROR(EINVAL);
3633 case 'a' : audio_codec_name = arg; break;
3634 case 's' : subtitle_codec_name = arg; break;
3635 case 'v' : video_codec_name = arg; break;
3637 av_log(NULL, AV_LOG_ERROR,
3638 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3639 return AVERROR(EINVAL);
3646 static const OptionDef options[] = {
3647 #include "cmdutils_common_opts.h"
3648 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3649 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3650 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3651 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3652 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3653 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3654 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3655 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3656 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3657 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3658 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3659 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3660 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3661 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3662 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3663 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3664 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3665 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3666 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3667 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3668 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3669 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3670 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3671 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3672 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3673 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3674 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3675 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3676 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3678 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3679 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3681 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3682 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3683 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3684 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3685 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3686 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3687 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3688 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3689 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3693 static void show_usage(void)
3695 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3696 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3697 av_log(NULL, AV_LOG_INFO, "\n");
3700 void show_help_default(const char *opt, const char *arg)
3702 av_log_set_callback(log_callback_help);
3704 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3705 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3707 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3708 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3709 #if !CONFIG_AVFILTER
3710 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3712 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3714 printf("\nWhile playing:\n"
3716 "f toggle full screen\n"
3719 "9, 0 decrease and increase volume respectively\n"
3720 "/, * decrease and increase volume respectively\n"
3721 "a cycle audio channel in the current program\n"
3722 "v cycle video channel\n"
3723 "t cycle subtitle channel in the current program\n"
3725 "w cycle video filters or show modes\n"
3726 "s activate frame-step mode\n"
3727 "left/right seek backward/forward 10 seconds\n"
3728 "down/up seek backward/forward 1 minute\n"
3729 "page down/page up seek backward/forward 10 minutes\n"
3730 "mouse click seek to percentage in file corresponding to fraction of width\n"
3734 static int lockmgr(void **mtx, enum AVLockOp op)
3737 case AV_LOCK_CREATE:
3738 *mtx = SDL_CreateMutex();
3740 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3744 case AV_LOCK_OBTAIN:
3745 return !!SDL_LockMutex(*mtx);
3746 case AV_LOCK_RELEASE:
3747 return !!SDL_UnlockMutex(*mtx);
3748 case AV_LOCK_DESTROY:
3749 SDL_DestroyMutex(*mtx);
3755 /* Called from the main */
3756 int main(int argc, char **argv)
3760 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3762 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3763 parse_loglevel(argc, argv, options);
3765 /* register all codecs, demux and protocols */
3767 avdevice_register_all();
3770 avfilter_register_all();
3773 avformat_network_init();
3777 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3778 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3780 show_banner(argc, argv, options);
3782 parse_options(NULL, argc, argv, options, opt_input_file);
3784 if (!input_filename) {
3786 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3787 av_log(NULL, AV_LOG_FATAL,
3788 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3792 if (display_disable) {
3795 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3797 flags &= ~SDL_INIT_AUDIO;
3798 if (display_disable)
3799 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3800 #if !defined(_WIN32) && !defined(__APPLE__)
3801 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3803 if (SDL_Init (flags)) {
3804 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3805 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3809 if (!display_disable) {
3810 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3811 fs_screen_width = vi->current_w;
3812 fs_screen_height = vi->current_h;
3815 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3816 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3817 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3819 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3821 if (av_lockmgr_register(lockmgr)) {
3822 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3826 av_init_packet(&flush_pkt);
3827 flush_pkt.data = (uint8_t *)&flush_pkt;
3829 is = stream_open(input_filename, file_iformat);
3831 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");