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;
248 unsigned int audio_buf_size; /* in bytes */
249 unsigned int audio_buf1_size;
250 int audio_buf_index; /* in bytes */
251 int audio_write_buf_size;
254 struct AudioParams audio_src;
256 struct AudioParams audio_filter_src;
258 struct AudioParams audio_tgt;
259 struct SwrContext *swr_ctx;
260 int frame_drops_early;
261 int frame_drops_late;
264 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
266 int16_t sample_array[SAMPLE_ARRAY_SIZE];
267 int sample_array_index;
271 FFTSample *rdft_data;
273 double last_vis_time;
276 AVStream *subtitle_st;
277 PacketQueue subtitleq;
280 double frame_last_returned_time;
281 double frame_last_filter_delay;
285 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
287 struct SwsContext *img_convert_ctx;
289 struct SwsContext *sub_convert_ctx;
290 SDL_Rect last_display_rect;
294 int width, height, xleft, ytop;
299 AVFilterContext *in_video_filter; // the first filter in the video chain
300 AVFilterContext *out_video_filter; // the last filter in the video chain
301 AVFilterContext *in_audio_filter; // the first filter in the audio chain
302 AVFilterContext *out_audio_filter; // the last filter in the audio chain
303 AVFilterGraph *agraph; // audio filter graph
306 int last_video_stream, last_audio_stream, last_subtitle_stream;
308 SDL_cond *continue_read_thread;
311 /* options specified by the user */
312 static AVInputFormat *file_iformat;
313 static const char *input_filename;
314 static const char *window_title;
315 static int fs_screen_width;
316 static int fs_screen_height;
317 static int default_width = 640;
318 static int default_height = 480;
319 static int screen_width = 0;
320 static int screen_height = 0;
321 static int audio_disable;
322 static int video_disable;
323 static int subtitle_disable;
324 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
325 static int seek_by_bytes = -1;
326 static int display_disable;
327 static int show_status = 1;
328 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
329 static int64_t start_time = AV_NOPTS_VALUE;
330 static int64_t duration = AV_NOPTS_VALUE;
332 static int genpts = 0;
333 static int lowres = 0;
334 static int decoder_reorder_pts = -1;
336 static int exit_on_keydown;
337 static int exit_on_mousedown;
339 static int framedrop = -1;
340 static int infinite_buffer = -1;
341 static enum ShowMode show_mode = SHOW_MODE_NONE;
342 static const char *audio_codec_name;
343 static const char *subtitle_codec_name;
344 static const char *video_codec_name;
345 double rdftspeed = 0.02;
346 static int64_t cursor_last_shown;
347 static int cursor_hidden = 0;
349 static const char **vfilters_list = NULL;
350 static int nb_vfilters = 0;
351 static char *afilters = NULL;
353 static int autorotate = 1;
355 /* current context */
356 static int is_full_screen;
357 static int64_t audio_callback_time;
359 static AVPacket flush_pkt;
361 #define FF_ALLOC_EVENT (SDL_USEREVENT)
362 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
364 static SDL_Surface *screen;
367 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
369 GROW_ARRAY(vfilters_list, nb_vfilters);
370 vfilters_list[nb_vfilters - 1] = arg;
376 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
377 enum AVSampleFormat fmt2, int64_t channel_count2)
379 /* If channel count == 1, planar and non-planar formats are the same */
380 if (channel_count1 == 1 && channel_count2 == 1)
381 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
383 return channel_count1 != channel_count2 || fmt1 != fmt2;
387 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
389 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
390 return channel_layout;
395 static void free_picture(Frame *vp);
397 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
399 MyAVPacketList *pkt1;
401 if (q->abort_request)
404 pkt1 = av_malloc(sizeof(MyAVPacketList));
409 if (pkt == &flush_pkt)
411 pkt1->serial = q->serial;
416 q->last_pkt->next = pkt1;
419 q->size += pkt1->pkt.size + sizeof(*pkt1);
420 /* XXX: should duplicate packet data in DV case */
421 SDL_CondSignal(q->cond);
425 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
429 SDL_LockMutex(q->mutex);
430 ret = packet_queue_put_private(q, pkt);
431 SDL_UnlockMutex(q->mutex);
433 if (pkt != &flush_pkt && ret < 0)
434 av_packet_unref(pkt);
439 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
441 AVPacket pkt1, *pkt = &pkt1;
445 pkt->stream_index = stream_index;
446 return packet_queue_put(q, pkt);
449 /* packet queue handling */
450 static int packet_queue_init(PacketQueue *q)
452 memset(q, 0, sizeof(PacketQueue));
453 q->mutex = SDL_CreateMutex();
455 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
456 return AVERROR(ENOMEM);
458 q->cond = SDL_CreateCond();
460 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
461 return AVERROR(ENOMEM);
463 q->abort_request = 1;
467 static void packet_queue_flush(PacketQueue *q)
469 MyAVPacketList *pkt, *pkt1;
471 SDL_LockMutex(q->mutex);
472 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
474 av_packet_unref(&pkt->pkt);
481 SDL_UnlockMutex(q->mutex);
484 static void packet_queue_destroy(PacketQueue *q)
486 packet_queue_flush(q);
487 SDL_DestroyMutex(q->mutex);
488 SDL_DestroyCond(q->cond);
491 static void packet_queue_abort(PacketQueue *q)
493 SDL_LockMutex(q->mutex);
495 q->abort_request = 1;
497 SDL_CondSignal(q->cond);
499 SDL_UnlockMutex(q->mutex);
502 static void packet_queue_start(PacketQueue *q)
504 SDL_LockMutex(q->mutex);
505 q->abort_request = 0;
506 packet_queue_put_private(q, &flush_pkt);
507 SDL_UnlockMutex(q->mutex);
510 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
511 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
513 MyAVPacketList *pkt1;
516 SDL_LockMutex(q->mutex);
519 if (q->abort_request) {
526 q->first_pkt = pkt1->next;
530 q->size -= pkt1->pkt.size + sizeof(*pkt1);
533 *serial = pkt1->serial;
541 SDL_CondWait(q->cond, q->mutex);
544 SDL_UnlockMutex(q->mutex);
548 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
549 memset(d, 0, sizeof(Decoder));
552 d->empty_queue_cond = empty_queue_cond;
553 d->start_pts = AV_NOPTS_VALUE;
556 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
562 if (d->queue->abort_request)
565 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
568 if (d->queue->nb_packets == 0)
569 SDL_CondSignal(d->empty_queue_cond);
570 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
572 if (pkt.data == flush_pkt.data) {
573 avcodec_flush_buffers(d->avctx);
575 d->next_pts = d->start_pts;
576 d->next_pts_tb = d->start_pts_tb;
578 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
579 av_packet_unref(&d->pkt);
580 d->pkt_temp = d->pkt = pkt;
581 d->packet_pending = 1;
584 switch (d->avctx->codec_type) {
585 case AVMEDIA_TYPE_VIDEO:
586 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
588 if (decoder_reorder_pts == -1) {
589 frame->pts = av_frame_get_best_effort_timestamp(frame);
590 } else if (decoder_reorder_pts) {
591 frame->pts = frame->pkt_pts;
593 frame->pts = frame->pkt_dts;
597 case AVMEDIA_TYPE_AUDIO:
598 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
600 AVRational tb = (AVRational){1, frame->sample_rate};
601 if (frame->pts != AV_NOPTS_VALUE)
602 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
603 else if (frame->pkt_pts != AV_NOPTS_VALUE)
604 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
605 else if (d->next_pts != AV_NOPTS_VALUE)
606 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
607 if (frame->pts != AV_NOPTS_VALUE) {
608 d->next_pts = frame->pts + frame->nb_samples;
613 case AVMEDIA_TYPE_SUBTITLE:
614 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
619 d->packet_pending = 0;
622 d->pkt_temp.pts = AV_NOPTS_VALUE;
623 if (d->pkt_temp.data) {
624 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
625 ret = d->pkt_temp.size;
626 d->pkt_temp.data += ret;
627 d->pkt_temp.size -= ret;
628 if (d->pkt_temp.size <= 0)
629 d->packet_pending = 0;
632 d->packet_pending = 0;
633 d->finished = d->pkt_serial;
637 } while (!got_frame && !d->finished);
642 static void decoder_destroy(Decoder *d) {
643 av_packet_unref(&d->pkt);
646 static void frame_queue_unref_item(Frame *vp)
649 for (i = 0; i < vp->sub.num_rects; i++) {
650 av_freep(&vp->subrects[i]->data[0]);
651 av_freep(&vp->subrects[i]);
653 av_freep(&vp->subrects);
654 av_frame_unref(vp->frame);
655 avsubtitle_free(&vp->sub);
658 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
661 memset(f, 0, sizeof(FrameQueue));
662 if (!(f->mutex = SDL_CreateMutex())) {
663 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
664 return AVERROR(ENOMEM);
666 if (!(f->cond = SDL_CreateCond())) {
667 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
668 return AVERROR(ENOMEM);
671 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
672 f->keep_last = !!keep_last;
673 for (i = 0; i < f->max_size; i++)
674 if (!(f->queue[i].frame = av_frame_alloc()))
675 return AVERROR(ENOMEM);
679 static void frame_queue_destory(FrameQueue *f)
682 for (i = 0; i < f->max_size; i++) {
683 Frame *vp = &f->queue[i];
684 frame_queue_unref_item(vp);
685 av_frame_free(&vp->frame);
688 SDL_DestroyMutex(f->mutex);
689 SDL_DestroyCond(f->cond);
692 static void frame_queue_signal(FrameQueue *f)
694 SDL_LockMutex(f->mutex);
695 SDL_CondSignal(f->cond);
696 SDL_UnlockMutex(f->mutex);
699 static Frame *frame_queue_peek(FrameQueue *f)
701 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
704 static Frame *frame_queue_peek_next(FrameQueue *f)
706 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
709 static Frame *frame_queue_peek_last(FrameQueue *f)
711 return &f->queue[f->rindex];
714 static Frame *frame_queue_peek_writable(FrameQueue *f)
716 /* wait until we have space to put a new frame */
717 SDL_LockMutex(f->mutex);
718 while (f->size >= f->max_size &&
719 !f->pktq->abort_request) {
720 SDL_CondWait(f->cond, f->mutex);
722 SDL_UnlockMutex(f->mutex);
724 if (f->pktq->abort_request)
727 return &f->queue[f->windex];
730 static Frame *frame_queue_peek_readable(FrameQueue *f)
732 /* wait until we have a readable a new frame */
733 SDL_LockMutex(f->mutex);
734 while (f->size - f->rindex_shown <= 0 &&
735 !f->pktq->abort_request) {
736 SDL_CondWait(f->cond, f->mutex);
738 SDL_UnlockMutex(f->mutex);
740 if (f->pktq->abort_request)
743 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
746 static void frame_queue_push(FrameQueue *f)
748 if (++f->windex == f->max_size)
750 SDL_LockMutex(f->mutex);
752 SDL_CondSignal(f->cond);
753 SDL_UnlockMutex(f->mutex);
756 static void frame_queue_next(FrameQueue *f)
758 if (f->keep_last && !f->rindex_shown) {
762 frame_queue_unref_item(&f->queue[f->rindex]);
763 if (++f->rindex == f->max_size)
765 SDL_LockMutex(f->mutex);
767 SDL_CondSignal(f->cond);
768 SDL_UnlockMutex(f->mutex);
771 /* jump back to the previous frame if available by resetting rindex_shown */
772 static int frame_queue_prev(FrameQueue *f)
774 int ret = f->rindex_shown;
779 /* return the number of undisplayed frames in the queue */
780 static int frame_queue_nb_remaining(FrameQueue *f)
782 return f->size - f->rindex_shown;
785 /* return last shown position */
786 static int64_t frame_queue_last_pos(FrameQueue *f)
788 Frame *fp = &f->queue[f->rindex];
789 if (f->rindex_shown && fp->serial == f->pktq->serial)
795 static void decoder_abort(Decoder *d, FrameQueue *fq)
797 packet_queue_abort(d->queue);
798 frame_queue_signal(fq);
799 SDL_WaitThread(d->decoder_tid, NULL);
800 d->decoder_tid = NULL;
801 packet_queue_flush(d->queue);
804 static inline void fill_rectangle(SDL_Surface *screen,
805 int x, int y, int w, int h, int color, int update)
812 SDL_FillRect(screen, &rect, color);
813 if (update && w > 0 && h > 0)
814 SDL_UpdateRect(screen, x, y, w, h);
817 /* draw only the border of a rectangle */
818 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
822 /* fill the background */
826 w2 = width - (x + w);
832 h2 = height - (y + h);
835 fill_rectangle(screen,
839 fill_rectangle(screen,
840 xleft + width - w2, ytop,
843 fill_rectangle(screen,
847 fill_rectangle(screen,
848 xleft + w1, ytop + height - h2,
853 #define ALPHA_BLEND(a, oldp, newp, s)\
854 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
860 static void blend_subrect(uint8_t **data, int *linesize, const AVSubtitleRect *rect, int imgw, int imgh)
862 int x, y, Y, U, V, A;
863 uint8_t *lum, *cb, *cr;
864 int dstx, dsty, dstw, dsth;
865 const AVSubtitleRect *src = rect;
867 dstw = av_clip(rect->w, 0, imgw);
868 dsth = av_clip(rect->h, 0, imgh);
869 dstx = av_clip(rect->x, 0, imgw - dstw);
870 dsty = av_clip(rect->y, 0, imgh - dsth);
871 lum = data[0] + dstx + dsty * linesize[0];
872 cb = data[1] + dstx/2 + (dsty >> 1) * linesize[1];
873 cr = data[2] + dstx/2 + (dsty >> 1) * linesize[2];
875 for (y = 0; y<dsth; y++) {
876 for (x = 0; x<dstw; x++) {
877 Y = src->data[0][x + y*src->linesize[0]];
878 A = src->data[3][x + y*src->linesize[3]];
879 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
882 lum += linesize[0] - dstw;
885 for (y = 0; y<dsth/2; y++) {
886 for (x = 0; x<dstw/2; x++) {
887 U = src->data[1][x + y*src->linesize[1]];
888 V = src->data[2][x + y*src->linesize[2]];
889 A = src->data[3][2*x + 2*y *src->linesize[3]]
890 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
891 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
892 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
893 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
894 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
898 cb += linesize[1] - dstw/2;
899 cr += linesize[2] - dstw/2;
903 static void free_picture(Frame *vp)
906 SDL_FreeYUVOverlay(vp->bmp);
911 static void calculate_display_rect(SDL_Rect *rect,
912 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
913 int pic_width, int pic_height, AVRational pic_sar)
916 int width, height, x, y;
918 if (pic_sar.num == 0)
921 aspect_ratio = av_q2d(pic_sar);
923 if (aspect_ratio <= 0.0)
925 aspect_ratio *= (float)pic_width / (float)pic_height;
927 /* XXX: we suppose the screen has a 1.0 pixel ratio */
929 width = lrint(height * aspect_ratio) & ~1;
930 if (width > scr_width) {
932 height = lrint(width / aspect_ratio) & ~1;
934 x = (scr_width - width) / 2;
935 y = (scr_height - height) / 2;
936 rect->x = scr_xleft + x;
937 rect->y = scr_ytop + y;
938 rect->w = FFMAX(width, 1);
939 rect->h = FFMAX(height, 1);
942 static void video_image_display(VideoState *is)
949 vp = frame_queue_peek(&is->pictq);
951 if (is->subtitle_st) {
952 if (frame_queue_nb_remaining(&is->subpq) > 0) {
953 sp = frame_queue_peek(&is->subpq);
955 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
959 SDL_LockYUVOverlay (vp->bmp);
961 data[0] = vp->bmp->pixels[0];
962 data[1] = vp->bmp->pixels[2];
963 data[2] = vp->bmp->pixels[1];
965 linesize[0] = vp->bmp->pitches[0];
966 linesize[1] = vp->bmp->pitches[2];
967 linesize[2] = vp->bmp->pitches[1];
969 for (i = 0; i < sp->sub.num_rects; i++)
970 blend_subrect(data, linesize, sp->subrects[i],
971 vp->bmp->w, vp->bmp->h);
973 SDL_UnlockYUVOverlay (vp->bmp);
978 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
980 SDL_DisplayYUVOverlay(vp->bmp, &rect);
982 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) {
983 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
984 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
985 is->last_display_rect = rect;
990 static inline int compute_mod(int a, int b)
992 return a < 0 ? a%b + b : a%b;
995 static void video_audio_display(VideoState *s)
997 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
998 int ch, channels, h, h2, bgcolor, fgcolor;
1000 int rdft_bits, nb_freq;
1002 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1004 nb_freq = 1 << (rdft_bits - 1);
1006 /* compute display index : center on currently output samples */
1007 channels = s->audio_tgt.channels;
1008 nb_display_channels = channels;
1010 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1012 delay = s->audio_write_buf_size;
1015 /* to be more precise, we take into account the time spent since
1016 the last buffer computation */
1017 if (audio_callback_time) {
1018 time_diff = av_gettime_relative() - audio_callback_time;
1019 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1022 delay += 2 * data_used;
1023 if (delay < data_used)
1026 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1027 if (s->show_mode == SHOW_MODE_WAVES) {
1029 for (i = 0; i < 1000; i += channels) {
1030 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1031 int a = s->sample_array[idx];
1032 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1033 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1034 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1036 if (h < score && (b ^ c) < 0) {
1043 s->last_i_start = i_start;
1045 i_start = s->last_i_start;
1048 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1049 if (s->show_mode == SHOW_MODE_WAVES) {
1050 fill_rectangle(screen,
1051 s->xleft, s->ytop, s->width, s->height,
1054 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1056 /* total height for one channel */
1057 h = s->height / nb_display_channels;
1058 /* graph height / 2 */
1060 for (ch = 0; ch < nb_display_channels; ch++) {
1062 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1063 for (x = 0; x < s->width; x++) {
1064 y = (s->sample_array[i] * h2) >> 15;
1071 fill_rectangle(screen,
1072 s->xleft + x, ys, 1, y,
1075 if (i >= SAMPLE_ARRAY_SIZE)
1076 i -= SAMPLE_ARRAY_SIZE;
1080 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1082 for (ch = 1; ch < nb_display_channels; ch++) {
1083 y = s->ytop + ch * h;
1084 fill_rectangle(screen,
1085 s->xleft, y, s->width, 1,
1088 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1090 nb_display_channels= FFMIN(nb_display_channels, 2);
1091 if (rdft_bits != s->rdft_bits) {
1092 av_rdft_end(s->rdft);
1093 av_free(s->rdft_data);
1094 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1095 s->rdft_bits = rdft_bits;
1096 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1098 if (!s->rdft || !s->rdft_data){
1099 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1100 s->show_mode = SHOW_MODE_WAVES;
1103 for (ch = 0; ch < nb_display_channels; ch++) {
1104 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1106 for (x = 0; x < 2 * nb_freq; x++) {
1107 double w = (x-nb_freq) * (1.0 / nb_freq);
1108 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1110 if (i >= SAMPLE_ARRAY_SIZE)
1111 i -= SAMPLE_ARRAY_SIZE;
1113 av_rdft_calc(s->rdft, data[ch]);
1115 /* Least efficient way to do this, we should of course
1116 * directly access it but it is more than fast enough. */
1117 for (y = 0; y < s->height; y++) {
1118 double w = 1 / sqrt(nb_freq);
1119 int a = sqrt(w * hypot(data[0][2 * y + 0], data[0][2 * y + 1]));
1120 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1124 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1126 fill_rectangle(screen,
1127 s->xpos, s->height-y, 1, 1,
1131 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1134 if (s->xpos >= s->width)
1139 static void stream_component_close(VideoState *is, int stream_index)
1141 AVFormatContext *ic = is->ic;
1142 AVCodecContext *avctx;
1144 if (stream_index < 0 || stream_index >= ic->nb_streams)
1146 avctx = ic->streams[stream_index]->codec;
1148 switch (avctx->codec_type) {
1149 case AVMEDIA_TYPE_AUDIO:
1150 decoder_abort(&is->auddec, &is->sampq);
1152 decoder_destroy(&is->auddec);
1153 swr_free(&is->swr_ctx);
1154 av_freep(&is->audio_buf1);
1155 is->audio_buf1_size = 0;
1156 is->audio_buf = NULL;
1159 av_rdft_end(is->rdft);
1160 av_freep(&is->rdft_data);
1165 case AVMEDIA_TYPE_VIDEO:
1166 decoder_abort(&is->viddec, &is->pictq);
1167 decoder_destroy(&is->viddec);
1169 case AVMEDIA_TYPE_SUBTITLE:
1170 decoder_abort(&is->subdec, &is->subpq);
1171 decoder_destroy(&is->subdec);
1177 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1178 avcodec_close(avctx);
1179 switch (avctx->codec_type) {
1180 case AVMEDIA_TYPE_AUDIO:
1181 is->audio_st = NULL;
1182 is->audio_stream = -1;
1184 case AVMEDIA_TYPE_VIDEO:
1185 is->video_st = NULL;
1186 is->video_stream = -1;
1188 case AVMEDIA_TYPE_SUBTITLE:
1189 is->subtitle_st = NULL;
1190 is->subtitle_stream = -1;
1197 static void stream_close(VideoState *is)
1199 /* XXX: use a special url_shutdown call to abort parse cleanly */
1200 is->abort_request = 1;
1201 SDL_WaitThread(is->read_tid, NULL);
1203 /* close each stream */
1204 if (is->audio_stream >= 0)
1205 stream_component_close(is, is->audio_stream);
1206 if (is->video_stream >= 0)
1207 stream_component_close(is, is->video_stream);
1208 if (is->subtitle_stream >= 0)
1209 stream_component_close(is, is->subtitle_stream);
1211 avformat_close_input(&is->ic);
1213 packet_queue_destroy(&is->videoq);
1214 packet_queue_destroy(&is->audioq);
1215 packet_queue_destroy(&is->subtitleq);
1217 /* free all pictures */
1218 frame_queue_destory(&is->pictq);
1219 frame_queue_destory(&is->sampq);
1220 frame_queue_destory(&is->subpq);
1221 SDL_DestroyCond(is->continue_read_thread);
1222 #if !CONFIG_AVFILTER
1223 sws_freeContext(is->img_convert_ctx);
1225 sws_freeContext(is->sub_convert_ctx);
1226 av_free(is->filename);
1230 static void do_exit(VideoState *is)
1235 av_lockmgr_register(NULL);
1238 av_freep(&vfilters_list);
1240 avformat_network_deinit();
1244 av_log(NULL, AV_LOG_QUIET, "%s", "");
1248 static void sigterm_handler(int sig)
1253 static void set_default_window_size(int width, int height, AVRational sar)
1256 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1257 default_width = rect.w;
1258 default_height = rect.h;
1261 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1263 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1266 if (is_full_screen) flags |= SDL_FULLSCREEN;
1267 else flags |= SDL_RESIZABLE;
1269 if (vp && vp->width)
1270 set_default_window_size(vp->width, vp->height, vp->sar);
1272 if (is_full_screen && fs_screen_width) {
1273 w = fs_screen_width;
1274 h = fs_screen_height;
1275 } else if (!is_full_screen && screen_width) {
1282 w = FFMIN(16383, w);
1283 if (screen && is->width == screen->w && screen->w == w
1284 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1286 screen = SDL_SetVideoMode(w, h, 0, flags);
1288 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1292 window_title = input_filename;
1293 SDL_WM_SetCaption(window_title, window_title);
1295 is->width = screen->w;
1296 is->height = screen->h;
1301 /* display the current picture, if any */
1302 static void video_display(VideoState *is)
1305 video_open(is, 0, NULL);
1306 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1307 video_audio_display(is);
1308 else if (is->video_st)
1309 video_image_display(is);
1312 static double get_clock(Clock *c)
1314 if (*c->queue_serial != c->serial)
1319 double time = av_gettime_relative() / 1000000.0;
1320 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1324 static void set_clock_at(Clock *c, double pts, int serial, double time)
1327 c->last_updated = time;
1328 c->pts_drift = c->pts - time;
1332 static void set_clock(Clock *c, double pts, int serial)
1334 double time = av_gettime_relative() / 1000000.0;
1335 set_clock_at(c, pts, serial, time);
1338 static void set_clock_speed(Clock *c, double speed)
1340 set_clock(c, get_clock(c), c->serial);
1344 static void init_clock(Clock *c, int *queue_serial)
1348 c->queue_serial = queue_serial;
1349 set_clock(c, NAN, -1);
1352 static void sync_clock_to_slave(Clock *c, Clock *slave)
1354 double clock = get_clock(c);
1355 double slave_clock = get_clock(slave);
1356 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1357 set_clock(c, slave_clock, slave->serial);
1360 static int get_master_sync_type(VideoState *is) {
1361 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1363 return AV_SYNC_VIDEO_MASTER;
1365 return AV_SYNC_AUDIO_MASTER;
1366 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1368 return AV_SYNC_AUDIO_MASTER;
1370 return AV_SYNC_EXTERNAL_CLOCK;
1372 return AV_SYNC_EXTERNAL_CLOCK;
1376 /* get the current master clock value */
1377 static double get_master_clock(VideoState *is)
1381 switch (get_master_sync_type(is)) {
1382 case AV_SYNC_VIDEO_MASTER:
1383 val = get_clock(&is->vidclk);
1385 case AV_SYNC_AUDIO_MASTER:
1386 val = get_clock(&is->audclk);
1389 val = get_clock(&is->extclk);
1395 static void check_external_clock_speed(VideoState *is) {
1396 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1397 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1398 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1399 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1400 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1401 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1403 double speed = is->extclk.speed;
1405 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1409 /* seek in the stream */
1410 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1412 if (!is->seek_req) {
1415 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1417 is->seek_flags |= AVSEEK_FLAG_BYTE;
1419 SDL_CondSignal(is->continue_read_thread);
1423 /* pause or resume the video */
1424 static void stream_toggle_pause(VideoState *is)
1427 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1428 if (is->read_pause_return != AVERROR(ENOSYS)) {
1429 is->vidclk.paused = 0;
1431 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1433 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1434 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1437 static void toggle_pause(VideoState *is)
1439 stream_toggle_pause(is);
1443 static void toggle_mute(VideoState *is)
1445 is->muted = !is->muted;
1448 static void update_volume(VideoState *is, int sign, int step)
1450 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1453 static void step_to_next_frame(VideoState *is)
1455 /* if the stream is paused unpause it, then step */
1457 stream_toggle_pause(is);
1461 static double compute_target_delay(double delay, VideoState *is)
1463 double sync_threshold, diff = 0;
1465 /* update delay to follow master synchronisation source */
1466 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1467 /* if video is slave, we try to correct big delays by
1468 duplicating or deleting a frame */
1469 diff = get_clock(&is->vidclk) - get_master_clock(is);
1471 /* skip or repeat frame. We take into account the
1472 delay to compute the threshold. I still don't know
1473 if it is the best guess */
1474 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1475 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1476 if (diff <= -sync_threshold)
1477 delay = FFMAX(0, delay + diff);
1478 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1479 delay = delay + diff;
1480 else if (diff >= sync_threshold)
1485 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1491 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1492 if (vp->serial == nextvp->serial) {
1493 double duration = nextvp->pts - vp->pts;
1494 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1495 return vp->duration;
1503 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1504 /* update current video pts */
1505 set_clock(&is->vidclk, pts, serial);
1506 sync_clock_to_slave(&is->extclk, &is->vidclk);
1509 /* called to display each frame */
1510 static void video_refresh(void *opaque, double *remaining_time)
1512 VideoState *is = opaque;
1517 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1518 check_external_clock_speed(is);
1520 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1521 time = av_gettime_relative() / 1000000.0;
1522 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1524 is->last_vis_time = time;
1526 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1531 if (is->force_refresh)
1532 redisplay = frame_queue_prev(&is->pictq);
1534 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1535 // nothing to do, no picture to display in the queue
1537 double last_duration, duration, delay;
1540 /* dequeue the picture */
1541 lastvp = frame_queue_peek_last(&is->pictq);
1542 vp = frame_queue_peek(&is->pictq);
1544 if (vp->serial != is->videoq.serial) {
1545 frame_queue_next(&is->pictq);
1550 if (lastvp->serial != vp->serial && !redisplay)
1551 is->frame_timer = av_gettime_relative() / 1000000.0;
1556 /* compute nominal last_duration */
1557 last_duration = vp_duration(is, lastvp, vp);
1561 delay = compute_target_delay(last_duration, is);
1563 time= av_gettime_relative()/1000000.0;
1564 if (time < is->frame_timer + delay && !redisplay) {
1565 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1569 is->frame_timer += delay;
1570 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1571 is->frame_timer = time;
1573 SDL_LockMutex(is->pictq.mutex);
1574 if (!redisplay && !isnan(vp->pts))
1575 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1576 SDL_UnlockMutex(is->pictq.mutex);
1578 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1579 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1580 duration = vp_duration(is, vp, nextvp);
1581 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1583 is->frame_drops_late++;
1584 frame_queue_next(&is->pictq);
1590 if (is->subtitle_st) {
1591 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1592 sp = frame_queue_peek(&is->subpq);
1594 if (frame_queue_nb_remaining(&is->subpq) > 1)
1595 sp2 = frame_queue_peek_next(&is->subpq);
1599 if (sp->serial != is->subtitleq.serial
1600 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1601 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1603 frame_queue_next(&is->subpq);
1611 /* display picture */
1612 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1615 frame_queue_next(&is->pictq);
1617 if (is->step && !is->paused)
1618 stream_toggle_pause(is);
1621 is->force_refresh = 0;
1623 static int64_t last_time;
1625 int aqsize, vqsize, sqsize;
1628 cur_time = av_gettime_relative();
1629 if (!last_time || (cur_time - last_time) >= 30000) {
1634 aqsize = is->audioq.size;
1636 vqsize = is->videoq.size;
1637 if (is->subtitle_st)
1638 sqsize = is->subtitleq.size;
1640 if (is->audio_st && is->video_st)
1641 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1642 else if (is->video_st)
1643 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1644 else if (is->audio_st)
1645 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1646 av_log(NULL, AV_LOG_INFO,
1647 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1648 get_master_clock(is),
1649 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1651 is->frame_drops_early + is->frame_drops_late,
1655 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1656 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1658 last_time = cur_time;
1663 /* allocate a picture (needs to do that in main thread to avoid
1664 potential locking problems */
1665 static void alloc_picture(VideoState *is)
1670 vp = &is->pictq.queue[is->pictq.windex];
1674 video_open(is, 0, vp);
1676 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1679 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1680 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1681 /* SDL allocates a buffer smaller than requested if the video
1682 * overlay hardware is unable to support the requested size. */
1683 av_log(NULL, AV_LOG_FATAL,
1684 "Error: the video system does not support an image\n"
1685 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1686 "to reduce the image size.\n", vp->width, vp->height );
1690 SDL_LockMutex(is->pictq.mutex);
1692 SDL_CondSignal(is->pictq.cond);
1693 SDL_UnlockMutex(is->pictq.mutex);
1696 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1697 int i, width, height;
1699 for (i = 0; i < 3; i++) {
1706 if (bmp->pitches[i] > width) {
1707 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1708 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1714 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1718 #if defined(DEBUG_SYNC)
1719 printf("frame_type=%c pts=%0.3f\n",
1720 av_get_picture_type_char(src_frame->pict_type), pts);
1723 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1726 vp->sar = src_frame->sample_aspect_ratio;
1728 /* alloc or resize hardware picture buffer */
1729 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1730 vp->width != src_frame->width ||
1731 vp->height != src_frame->height) {
1736 vp->width = src_frame->width;
1737 vp->height = src_frame->height;
1739 /* the allocation must be done in the main thread to avoid
1740 locking problems. */
1741 event.type = FF_ALLOC_EVENT;
1742 event.user.data1 = is;
1743 SDL_PushEvent(&event);
1745 /* wait until the picture is allocated */
1746 SDL_LockMutex(is->pictq.mutex);
1747 while (!vp->allocated && !is->videoq.abort_request) {
1748 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1750 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1751 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1752 while (!vp->allocated && !is->abort_request) {
1753 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1756 SDL_UnlockMutex(is->pictq.mutex);
1758 if (is->videoq.abort_request)
1762 /* if the frame is not skipped, then display it */
1767 /* get a pointer on the bitmap */
1768 SDL_LockYUVOverlay (vp->bmp);
1770 data[0] = vp->bmp->pixels[0];
1771 data[1] = vp->bmp->pixels[2];
1772 data[2] = vp->bmp->pixels[1];
1774 linesize[0] = vp->bmp->pitches[0];
1775 linesize[1] = vp->bmp->pitches[2];
1776 linesize[2] = vp->bmp->pitches[1];
1779 // FIXME use direct rendering
1780 av_image_copy(data, linesize, (const uint8_t **)src_frame->data, src_frame->linesize,
1781 src_frame->format, vp->width, vp->height);
1784 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1786 const AVClass *class = sws_get_class();
1787 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1788 AV_OPT_SEARCH_FAKE_OBJ);
1789 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1795 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1796 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1797 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1798 if (!is->img_convert_ctx) {
1799 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1802 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1803 0, vp->height, data, linesize);
1805 /* workaround SDL PITCH_WORKAROUND */
1806 duplicate_right_border_pixels(vp->bmp);
1807 /* update the bitmap content */
1808 SDL_UnlockYUVOverlay(vp->bmp);
1811 vp->duration = duration;
1813 vp->serial = serial;
1815 /* now we can update the picture count */
1816 frame_queue_push(&is->pictq);
1821 static int get_video_frame(VideoState *is, AVFrame *frame)
1825 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1831 if (frame->pts != AV_NOPTS_VALUE)
1832 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1834 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1836 is->viddec_width = frame->width;
1837 is->viddec_height = frame->height;
1839 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1840 if (frame->pts != AV_NOPTS_VALUE) {
1841 double diff = dpts - get_master_clock(is);
1842 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1843 diff - is->frame_last_filter_delay < 0 &&
1844 is->viddec.pkt_serial == is->vidclk.serial &&
1845 is->videoq.nb_packets) {
1846 is->frame_drops_early++;
1847 av_frame_unref(frame);
1858 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1859 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1862 int nb_filters = graph->nb_filters;
1863 AVFilterInOut *outputs = NULL, *inputs = NULL;
1866 outputs = avfilter_inout_alloc();
1867 inputs = avfilter_inout_alloc();
1868 if (!outputs || !inputs) {
1869 ret = AVERROR(ENOMEM);
1873 outputs->name = av_strdup("in");
1874 outputs->filter_ctx = source_ctx;
1875 outputs->pad_idx = 0;
1876 outputs->next = NULL;
1878 inputs->name = av_strdup("out");
1879 inputs->filter_ctx = sink_ctx;
1880 inputs->pad_idx = 0;
1881 inputs->next = NULL;
1883 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1886 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1890 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1891 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1892 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1894 ret = avfilter_graph_config(graph, NULL);
1896 avfilter_inout_free(&outputs);
1897 avfilter_inout_free(&inputs);
1901 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1903 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1904 char sws_flags_str[512] = "";
1905 char buffersrc_args[256];
1907 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1908 AVCodecContext *codec = is->video_st->codec;
1909 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1910 AVDictionaryEntry *e = NULL;
1912 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1913 if (!strcmp(e->key, "sws_flags")) {
1914 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1916 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1918 if (strlen(sws_flags_str))
1919 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1921 graph->scale_sws_opts = av_strdup(sws_flags_str);
1923 snprintf(buffersrc_args, sizeof(buffersrc_args),
1924 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1925 frame->width, frame->height, frame->format,
1926 is->video_st->time_base.num, is->video_st->time_base.den,
1927 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1928 if (fr.num && fr.den)
1929 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1931 if ((ret = avfilter_graph_create_filter(&filt_src,
1932 avfilter_get_by_name("buffer"),
1933 "ffplay_buffer", buffersrc_args, NULL,
1937 ret = avfilter_graph_create_filter(&filt_out,
1938 avfilter_get_by_name("buffersink"),
1939 "ffplay_buffersink", NULL, NULL, graph);
1943 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1946 last_filter = filt_out;
1948 /* Note: this macro adds a filter before the lastly added filter, so the
1949 * processing order of the filters is in reverse */
1950 #define INSERT_FILT(name, arg) do { \
1951 AVFilterContext *filt_ctx; \
1953 ret = avfilter_graph_create_filter(&filt_ctx, \
1954 avfilter_get_by_name(name), \
1955 "ffplay_" name, arg, NULL, graph); \
1959 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1963 last_filter = filt_ctx; \
1966 /* SDL YUV code is not handling odd width/height for some driver
1967 * combinations, therefore we crop the picture to an even width/height. */
1968 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1971 double theta = get_rotation(is->video_st);
1973 if (fabs(theta - 90) < 1.0) {
1974 INSERT_FILT("transpose", "clock");
1975 } else if (fabs(theta - 180) < 1.0) {
1976 INSERT_FILT("hflip", NULL);
1977 INSERT_FILT("vflip", NULL);
1978 } else if (fabs(theta - 270) < 1.0) {
1979 INSERT_FILT("transpose", "cclock");
1980 } else if (fabs(theta) > 1.0) {
1981 char rotate_buf[64];
1982 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1983 INSERT_FILT("rotate", rotate_buf);
1987 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1990 is->in_video_filter = filt_src;
1991 is->out_video_filter = filt_out;
1997 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1999 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2000 int sample_rates[2] = { 0, -1 };
2001 int64_t channel_layouts[2] = { 0, -1 };
2002 int channels[2] = { 0, -1 };
2003 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2004 char aresample_swr_opts[512] = "";
2005 AVDictionaryEntry *e = NULL;
2006 char asrc_args[256];
2009 avfilter_graph_free(&is->agraph);
2010 if (!(is->agraph = avfilter_graph_alloc()))
2011 return AVERROR(ENOMEM);
2013 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2014 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2015 if (strlen(aresample_swr_opts))
2016 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2017 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2019 ret = snprintf(asrc_args, sizeof(asrc_args),
2020 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2021 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2022 is->audio_filter_src.channels,
2023 1, is->audio_filter_src.freq);
2024 if (is->audio_filter_src.channel_layout)
2025 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2026 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2028 ret = avfilter_graph_create_filter(&filt_asrc,
2029 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2030 asrc_args, NULL, is->agraph);
2035 ret = avfilter_graph_create_filter(&filt_asink,
2036 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2037 NULL, NULL, is->agraph);
2041 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2043 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2046 if (force_output_format) {
2047 channel_layouts[0] = is->audio_tgt.channel_layout;
2048 channels [0] = is->audio_tgt.channels;
2049 sample_rates [0] = is->audio_tgt.freq;
2050 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2052 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2054 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2056 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2061 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2064 is->in_audio_filter = filt_asrc;
2065 is->out_audio_filter = filt_asink;
2069 avfilter_graph_free(&is->agraph);
2072 #endif /* CONFIG_AVFILTER */
2074 static int audio_thread(void *arg)
2076 VideoState *is = arg;
2077 AVFrame *frame = av_frame_alloc();
2080 int last_serial = -1;
2081 int64_t dec_channel_layout;
2089 return AVERROR(ENOMEM);
2092 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2096 tb = (AVRational){1, frame->sample_rate};
2099 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2102 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2103 frame->format, av_frame_get_channels(frame)) ||
2104 is->audio_filter_src.channel_layout != dec_channel_layout ||
2105 is->audio_filter_src.freq != frame->sample_rate ||
2106 is->auddec.pkt_serial != last_serial;
2109 char buf1[1024], buf2[1024];
2110 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2111 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2112 av_log(NULL, AV_LOG_DEBUG,
2113 "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",
2114 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2115 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2117 is->audio_filter_src.fmt = frame->format;
2118 is->audio_filter_src.channels = av_frame_get_channels(frame);
2119 is->audio_filter_src.channel_layout = dec_channel_layout;
2120 is->audio_filter_src.freq = frame->sample_rate;
2121 last_serial = is->auddec.pkt_serial;
2123 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2127 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2130 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2131 tb = is->out_audio_filter->inputs[0]->time_base;
2133 if (!(af = frame_queue_peek_writable(&is->sampq)))
2136 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2137 af->pos = av_frame_get_pkt_pos(frame);
2138 af->serial = is->auddec.pkt_serial;
2139 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2141 av_frame_move_ref(af->frame, frame);
2142 frame_queue_push(&is->sampq);
2145 if (is->audioq.serial != is->auddec.pkt_serial)
2148 if (ret == AVERROR_EOF)
2149 is->auddec.finished = is->auddec.pkt_serial;
2152 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2155 avfilter_graph_free(&is->agraph);
2157 av_frame_free(&frame);
2161 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2163 packet_queue_start(d->queue);
2164 d->decoder_tid = SDL_CreateThread(fn, arg);
2165 if (!d->decoder_tid) {
2166 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2167 return AVERROR(ENOMEM);
2172 static int video_thread(void *arg)
2174 VideoState *is = arg;
2175 AVFrame *frame = av_frame_alloc();
2179 AVRational tb = is->video_st->time_base;
2180 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2183 AVFilterGraph *graph = avfilter_graph_alloc();
2184 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2187 enum AVPixelFormat last_format = -2;
2188 int last_serial = -1;
2189 int last_vfilter_idx = 0;
2191 av_frame_free(&frame);
2192 return AVERROR(ENOMEM);
2199 avfilter_graph_free(&graph);
2201 return AVERROR(ENOMEM);
2205 ret = get_video_frame(is, frame);
2212 if ( last_w != frame->width
2213 || last_h != frame->height
2214 || last_format != frame->format
2215 || last_serial != is->viddec.pkt_serial
2216 || last_vfilter_idx != is->vfilter_idx) {
2217 av_log(NULL, AV_LOG_DEBUG,
2218 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2220 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2221 frame->width, frame->height,
2222 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2223 avfilter_graph_free(&graph);
2224 graph = avfilter_graph_alloc();
2225 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2227 event.type = FF_QUIT_EVENT;
2228 event.user.data1 = is;
2229 SDL_PushEvent(&event);
2232 filt_in = is->in_video_filter;
2233 filt_out = is->out_video_filter;
2234 last_w = frame->width;
2235 last_h = frame->height;
2236 last_format = frame->format;
2237 last_serial = is->viddec.pkt_serial;
2238 last_vfilter_idx = is->vfilter_idx;
2239 frame_rate = filt_out->inputs[0]->frame_rate;
2242 ret = av_buffersrc_add_frame(filt_in, frame);
2247 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2249 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2251 if (ret == AVERROR_EOF)
2252 is->viddec.finished = is->viddec.pkt_serial;
2257 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2258 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2259 is->frame_last_filter_delay = 0;
2260 tb = filt_out->inputs[0]->time_base;
2262 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2263 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2264 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2265 av_frame_unref(frame);
2275 avfilter_graph_free(&graph);
2277 av_frame_free(&frame);
2281 static int subtitle_thread(void *arg)
2283 VideoState *is = arg;
2290 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2293 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2298 if (got_subtitle && sp->sub.format == 0) {
2299 if (sp->sub.pts != AV_NOPTS_VALUE)
2300 pts = sp->sub.pts / (double)AV_TIME_BASE;
2302 sp->serial = is->subdec.pkt_serial;
2303 if (!(sp->subrects = av_mallocz_array(sp->sub.num_rects, sizeof(AVSubtitleRect*)))) {
2304 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subrects\n");
2308 for (i = 0; i < sp->sub.num_rects; i++)
2310 int in_w = sp->sub.rects[i]->w;
2311 int in_h = sp->sub.rects[i]->h;
2312 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2313 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2314 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2315 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2317 if (!(sp->subrects[i] = av_mallocz(sizeof(AVSubtitleRect))) ||
2318 av_image_alloc(sp->subrects[i]->data, sp->subrects[i]->linesize, out_w, out_h, AV_PIX_FMT_YUVA420P, 16) < 0) {
2319 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subtitle data\n");
2323 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2324 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2325 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2326 if (!is->sub_convert_ctx) {
2327 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2330 sws_scale(is->sub_convert_ctx,
2331 (void*)sp->sub.rects[i]->data, sp->sub.rects[i]->linesize,
2332 0, in_h, sp->subrects[i]->data, sp->subrects[i]->linesize);
2334 sp->subrects[i]->w = out_w;
2335 sp->subrects[i]->h = out_h;
2336 sp->subrects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2337 sp->subrects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2340 /* now we can update the picture count */
2341 frame_queue_push(&is->subpq);
2342 } else if (got_subtitle) {
2343 avsubtitle_free(&sp->sub);
2349 /* copy samples for viewing in editor window */
2350 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2354 size = samples_size / sizeof(short);
2356 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2359 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2361 is->sample_array_index += len;
2362 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2363 is->sample_array_index = 0;
2368 /* return the wanted number of samples to get better sync if sync_type is video
2369 * or external master clock */
2370 static int synchronize_audio(VideoState *is, int nb_samples)
2372 int wanted_nb_samples = nb_samples;
2374 /* if not master, then we try to remove or add samples to correct the clock */
2375 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2376 double diff, avg_diff;
2377 int min_nb_samples, max_nb_samples;
2379 diff = get_clock(&is->audclk) - get_master_clock(is);
2381 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2382 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2383 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2384 /* not enough measures to have a correct estimate */
2385 is->audio_diff_avg_count++;
2387 /* estimate the A-V difference */
2388 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2390 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2391 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2392 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2393 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2394 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2396 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2397 diff, avg_diff, wanted_nb_samples - nb_samples,
2398 is->audio_clock, is->audio_diff_threshold);
2401 /* too big difference : may be initial PTS errors, so
2403 is->audio_diff_avg_count = 0;
2404 is->audio_diff_cum = 0;
2408 return wanted_nb_samples;
2412 * Decode one audio frame and return its uncompressed size.
2414 * The processed audio frame is decoded, converted if required, and
2415 * stored in is->audio_buf, with size in bytes given by the return
2418 static int audio_decode_frame(VideoState *is)
2420 int data_size, resampled_data_size;
2421 int64_t dec_channel_layout;
2422 av_unused double audio_clock0;
2423 int wanted_nb_samples;
2431 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2432 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2437 if (!(af = frame_queue_peek_readable(&is->sampq)))
2439 frame_queue_next(&is->sampq);
2440 } while (af->serial != is->audioq.serial);
2442 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2443 af->frame->nb_samples,
2444 af->frame->format, 1);
2446 dec_channel_layout =
2447 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2448 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2449 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2451 if (af->frame->format != is->audio_src.fmt ||
2452 dec_channel_layout != is->audio_src.channel_layout ||
2453 af->frame->sample_rate != is->audio_src.freq ||
2454 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2455 swr_free(&is->swr_ctx);
2456 is->swr_ctx = swr_alloc_set_opts(NULL,
2457 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2458 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2460 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2461 av_log(NULL, AV_LOG_ERROR,
2462 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2463 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2464 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2465 swr_free(&is->swr_ctx);
2468 is->audio_src.channel_layout = dec_channel_layout;
2469 is->audio_src.channels = av_frame_get_channels(af->frame);
2470 is->audio_src.freq = af->frame->sample_rate;
2471 is->audio_src.fmt = af->frame->format;
2475 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2476 uint8_t **out = &is->audio_buf1;
2477 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2478 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2481 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2484 if (wanted_nb_samples != af->frame->nb_samples) {
2485 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2486 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2487 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2491 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2492 if (!is->audio_buf1)
2493 return AVERROR(ENOMEM);
2494 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2496 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2499 if (len2 == out_count) {
2500 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2501 if (swr_init(is->swr_ctx) < 0)
2502 swr_free(&is->swr_ctx);
2504 is->audio_buf = is->audio_buf1;
2505 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2507 is->audio_buf = af->frame->data[0];
2508 resampled_data_size = data_size;
2511 audio_clock0 = is->audio_clock;
2512 /* update the audio clock with the pts */
2513 if (!isnan(af->pts))
2514 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2516 is->audio_clock = NAN;
2517 is->audio_clock_serial = af->serial;
2520 static double last_clock;
2521 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2522 is->audio_clock - last_clock,
2523 is->audio_clock, audio_clock0);
2524 last_clock = is->audio_clock;
2527 return resampled_data_size;
2530 /* prepare a new audio buffer */
2531 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2533 VideoState *is = opaque;
2534 int audio_size, len1;
2536 audio_callback_time = av_gettime_relative();
2539 if (is->audio_buf_index >= is->audio_buf_size) {
2540 audio_size = audio_decode_frame(is);
2541 if (audio_size < 0) {
2542 /* if error, just output silence */
2543 is->audio_buf = NULL;
2544 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2546 if (is->show_mode != SHOW_MODE_VIDEO)
2547 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2548 is->audio_buf_size = audio_size;
2550 is->audio_buf_index = 0;
2552 len1 = is->audio_buf_size - is->audio_buf_index;
2555 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2556 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2558 memset(stream, 0, len1);
2559 if (!is->muted && is->audio_buf)
2560 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2564 is->audio_buf_index += len1;
2566 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2567 /* Let's assume the audio driver that is used by SDL has two periods. */
2568 if (!isnan(is->audio_clock)) {
2569 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);
2570 sync_clock_to_slave(&is->extclk, &is->audclk);
2574 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2576 SDL_AudioSpec wanted_spec, spec;
2578 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2579 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2580 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2582 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2584 wanted_nb_channels = atoi(env);
2585 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2587 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2588 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2589 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2591 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2592 wanted_spec.channels = wanted_nb_channels;
2593 wanted_spec.freq = wanted_sample_rate;
2594 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2595 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2598 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2599 next_sample_rate_idx--;
2600 wanted_spec.format = AUDIO_S16SYS;
2601 wanted_spec.silence = 0;
2602 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2603 wanted_spec.callback = sdl_audio_callback;
2604 wanted_spec.userdata = opaque;
2605 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2606 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2607 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2608 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2609 if (!wanted_spec.channels) {
2610 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2611 wanted_spec.channels = wanted_nb_channels;
2612 if (!wanted_spec.freq) {
2613 av_log(NULL, AV_LOG_ERROR,
2614 "No more combinations to try, audio open failed\n");
2618 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2620 if (spec.format != AUDIO_S16SYS) {
2621 av_log(NULL, AV_LOG_ERROR,
2622 "SDL advised audio format %d is not supported!\n", spec.format);
2625 if (spec.channels != wanted_spec.channels) {
2626 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2627 if (!wanted_channel_layout) {
2628 av_log(NULL, AV_LOG_ERROR,
2629 "SDL advised channel count %d is not supported!\n", spec.channels);
2634 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2635 audio_hw_params->freq = spec.freq;
2636 audio_hw_params->channel_layout = wanted_channel_layout;
2637 audio_hw_params->channels = spec.channels;
2638 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2639 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);
2640 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2641 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2647 /* open a given stream. Return 0 if OK */
2648 static int stream_component_open(VideoState *is, int stream_index)
2650 AVFormatContext *ic = is->ic;
2651 AVCodecContext *avctx;
2653 const char *forced_codec_name = NULL;
2655 AVDictionaryEntry *t = NULL;
2656 int sample_rate, nb_channels;
2657 int64_t channel_layout;
2659 int stream_lowres = lowres;
2661 if (stream_index < 0 || stream_index >= ic->nb_streams)
2663 avctx = ic->streams[stream_index]->codec;
2665 codec = avcodec_find_decoder(avctx->codec_id);
2667 switch(avctx->codec_type){
2668 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2669 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2670 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2672 if (forced_codec_name)
2673 codec = avcodec_find_decoder_by_name(forced_codec_name);
2675 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2676 "No codec could be found with name '%s'\n", forced_codec_name);
2677 else av_log(NULL, AV_LOG_WARNING,
2678 "No codec could be found with id %d\n", avctx->codec_id);
2682 avctx->codec_id = codec->id;
2683 if(stream_lowres > av_codec_get_max_lowres(codec)){
2684 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2685 av_codec_get_max_lowres(codec));
2686 stream_lowres = av_codec_get_max_lowres(codec);
2688 av_codec_set_lowres(avctx, stream_lowres);
2691 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2694 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2696 if(codec->capabilities & AV_CODEC_CAP_DR1)
2697 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2700 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2701 if (!av_dict_get(opts, "threads", NULL, 0))
2702 av_dict_set(&opts, "threads", "auto", 0);
2704 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2705 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2706 av_dict_set(&opts, "refcounted_frames", "1", 0);
2707 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2710 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2711 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2712 ret = AVERROR_OPTION_NOT_FOUND;
2717 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2718 switch (avctx->codec_type) {
2719 case AVMEDIA_TYPE_AUDIO:
2724 is->audio_filter_src.freq = avctx->sample_rate;
2725 is->audio_filter_src.channels = avctx->channels;
2726 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2727 is->audio_filter_src.fmt = avctx->sample_fmt;
2728 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2730 link = is->out_audio_filter->inputs[0];
2731 sample_rate = link->sample_rate;
2732 nb_channels = link->channels;
2733 channel_layout = link->channel_layout;
2736 sample_rate = avctx->sample_rate;
2737 nb_channels = avctx->channels;
2738 channel_layout = avctx->channel_layout;
2741 /* prepare audio output */
2742 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2744 is->audio_hw_buf_size = ret;
2745 is->audio_src = is->audio_tgt;
2746 is->audio_buf_size = 0;
2747 is->audio_buf_index = 0;
2749 /* init averaging filter */
2750 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2751 is->audio_diff_avg_count = 0;
2752 /* since we do not have a precise anough audio fifo fullness,
2753 we correct audio sync only if larger than this threshold */
2754 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2756 is->audio_stream = stream_index;
2757 is->audio_st = ic->streams[stream_index];
2759 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2760 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2761 is->auddec.start_pts = is->audio_st->start_time;
2762 is->auddec.start_pts_tb = is->audio_st->time_base;
2764 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2768 case AVMEDIA_TYPE_VIDEO:
2769 is->video_stream = stream_index;
2770 is->video_st = ic->streams[stream_index];
2772 is->viddec_width = avctx->width;
2773 is->viddec_height = avctx->height;
2775 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2776 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2778 is->queue_attachments_req = 1;
2780 case AVMEDIA_TYPE_SUBTITLE:
2781 is->subtitle_stream = stream_index;
2782 is->subtitle_st = ic->streams[stream_index];
2784 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2785 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2793 av_dict_free(&opts);
2798 static int decode_interrupt_cb(void *ctx)
2800 VideoState *is = ctx;
2801 return is->abort_request;
2804 static int is_realtime(AVFormatContext *s)
2806 if( !strcmp(s->iformat->name, "rtp")
2807 || !strcmp(s->iformat->name, "rtsp")
2808 || !strcmp(s->iformat->name, "sdp")
2812 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2813 || !strncmp(s->filename, "udp:", 4)
2820 /* this thread gets the stream from the disk or the network */
2821 static int read_thread(void *arg)
2823 VideoState *is = arg;
2824 AVFormatContext *ic = NULL;
2826 int st_index[AVMEDIA_TYPE_NB];
2827 AVPacket pkt1, *pkt = &pkt1;
2828 int64_t stream_start_time;
2829 int pkt_in_play_range = 0;
2830 AVDictionaryEntry *t;
2831 AVDictionary **opts;
2832 int orig_nb_streams;
2833 SDL_mutex *wait_mutex = SDL_CreateMutex();
2834 int scan_all_pmts_set = 0;
2838 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2839 ret = AVERROR(ENOMEM);
2843 memset(st_index, -1, sizeof(st_index));
2844 is->last_video_stream = is->video_stream = -1;
2845 is->last_audio_stream = is->audio_stream = -1;
2846 is->last_subtitle_stream = is->subtitle_stream = -1;
2849 ic = avformat_alloc_context();
2851 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2852 ret = AVERROR(ENOMEM);
2855 ic->interrupt_callback.callback = decode_interrupt_cb;
2856 ic->interrupt_callback.opaque = is;
2857 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2858 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2859 scan_all_pmts_set = 1;
2861 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2863 print_error(is->filename, err);
2867 if (scan_all_pmts_set)
2868 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2870 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2871 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2872 ret = AVERROR_OPTION_NOT_FOUND;
2878 ic->flags |= AVFMT_FLAG_GENPTS;
2880 av_format_inject_global_side_data(ic);
2882 opts = setup_find_stream_info_opts(ic, codec_opts);
2883 orig_nb_streams = ic->nb_streams;
2885 err = avformat_find_stream_info(ic, opts);
2887 for (i = 0; i < orig_nb_streams; i++)
2888 av_dict_free(&opts[i]);
2892 av_log(NULL, AV_LOG_WARNING,
2893 "%s: could not find codec parameters\n", is->filename);
2899 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2901 if (seek_by_bytes < 0)
2902 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2904 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2906 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2907 window_title = av_asprintf("%s - %s", t->value, input_filename);
2909 /* if seeking requested, we execute it */
2910 if (start_time != AV_NOPTS_VALUE) {
2913 timestamp = start_time;
2914 /* add the stream start time */
2915 if (ic->start_time != AV_NOPTS_VALUE)
2916 timestamp += ic->start_time;
2917 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2919 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2920 is->filename, (double)timestamp / AV_TIME_BASE);
2924 is->realtime = is_realtime(ic);
2927 av_dump_format(ic, 0, is->filename, 0);
2929 for (i = 0; i < ic->nb_streams; i++) {
2930 AVStream *st = ic->streams[i];
2931 enum AVMediaType type = st->codec->codec_type;
2932 st->discard = AVDISCARD_ALL;
2933 if (wanted_stream_spec[type] && st_index[type] == -1)
2934 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2937 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2938 if (wanted_stream_spec[i] && st_index[i] == -1) {
2939 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));
2940 st_index[i] = INT_MAX;
2945 st_index[AVMEDIA_TYPE_VIDEO] =
2946 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2947 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2949 st_index[AVMEDIA_TYPE_AUDIO] =
2950 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2951 st_index[AVMEDIA_TYPE_AUDIO],
2952 st_index[AVMEDIA_TYPE_VIDEO],
2954 if (!video_disable && !subtitle_disable)
2955 st_index[AVMEDIA_TYPE_SUBTITLE] =
2956 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2957 st_index[AVMEDIA_TYPE_SUBTITLE],
2958 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2959 st_index[AVMEDIA_TYPE_AUDIO] :
2960 st_index[AVMEDIA_TYPE_VIDEO]),
2963 is->show_mode = show_mode;
2964 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2965 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2966 AVCodecContext *avctx = st->codec;
2967 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2969 set_default_window_size(avctx->width, avctx->height, sar);
2972 /* open the streams */
2973 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2974 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2978 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2979 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2981 if (is->show_mode == SHOW_MODE_NONE)
2982 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2984 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2985 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2988 if (is->video_stream < 0 && is->audio_stream < 0) {
2989 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2995 if (infinite_buffer < 0 && is->realtime)
2996 infinite_buffer = 1;
2999 if (is->abort_request)
3001 if (is->paused != is->last_paused) {
3002 is->last_paused = is->paused;
3004 is->read_pause_return = av_read_pause(ic);
3008 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3010 (!strcmp(ic->iformat->name, "rtsp") ||
3011 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3012 /* wait 10 ms to avoid trying to get another packet */
3019 int64_t seek_target = is->seek_pos;
3020 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3021 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3022 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3023 // of the seek_pos/seek_rel variables
3025 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3027 av_log(NULL, AV_LOG_ERROR,
3028 "%s: error while seeking\n", is->ic->filename);
3030 if (is->audio_stream >= 0) {
3031 packet_queue_flush(&is->audioq);
3032 packet_queue_put(&is->audioq, &flush_pkt);
3034 if (is->subtitle_stream >= 0) {
3035 packet_queue_flush(&is->subtitleq);
3036 packet_queue_put(&is->subtitleq, &flush_pkt);
3038 if (is->video_stream >= 0) {
3039 packet_queue_flush(&is->videoq);
3040 packet_queue_put(&is->videoq, &flush_pkt);
3042 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3043 set_clock(&is->extclk, NAN, 0);
3045 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3049 is->queue_attachments_req = 1;
3052 step_to_next_frame(is);
3054 if (is->queue_attachments_req) {
3055 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3057 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3059 packet_queue_put(&is->videoq, ©);
3060 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3062 is->queue_attachments_req = 0;
3065 /* if the queue are full, no need to read more */
3066 if (infinite_buffer<1 &&
3067 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3068 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3069 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3070 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3071 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3073 SDL_LockMutex(wait_mutex);
3074 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3075 SDL_UnlockMutex(wait_mutex);
3079 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3080 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3081 if (loop != 1 && (!loop || --loop)) {
3082 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3083 } else if (autoexit) {
3088 ret = av_read_frame(ic, pkt);
3090 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3091 if (is->video_stream >= 0)
3092 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3093 if (is->audio_stream >= 0)
3094 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3095 if (is->subtitle_stream >= 0)
3096 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3099 if (ic->pb && ic->pb->error)
3101 SDL_LockMutex(wait_mutex);
3102 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3103 SDL_UnlockMutex(wait_mutex);
3108 /* check if packet is in play range specified by user, then queue, otherwise discard */
3109 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3110 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3111 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3112 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3113 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3114 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3115 <= ((double)duration / 1000000);
3116 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3117 packet_queue_put(&is->audioq, pkt);
3118 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3119 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3120 packet_queue_put(&is->videoq, pkt);
3121 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3122 packet_queue_put(&is->subtitleq, pkt);
3124 av_packet_unref(pkt);
3131 avformat_close_input(&ic);
3136 event.type = FF_QUIT_EVENT;
3137 event.user.data1 = is;
3138 SDL_PushEvent(&event);
3140 SDL_DestroyMutex(wait_mutex);
3144 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3148 is = av_mallocz(sizeof(VideoState));
3151 is->filename = av_strdup(filename);
3154 is->iformat = iformat;
3158 /* start video display */
3159 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3161 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3163 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3166 if (packet_queue_init(&is->videoq) < 0 ||
3167 packet_queue_init(&is->audioq) < 0 ||
3168 packet_queue_init(&is->subtitleq) < 0)
3171 if (!(is->continue_read_thread = SDL_CreateCond())) {
3172 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3176 init_clock(&is->vidclk, &is->videoq.serial);
3177 init_clock(&is->audclk, &is->audioq.serial);
3178 init_clock(&is->extclk, &is->extclk.serial);
3179 is->audio_clock_serial = -1;
3180 is->audio_volume = SDL_MIX_MAXVOLUME;
3182 is->av_sync_type = av_sync_type;
3183 is->read_tid = SDL_CreateThread(read_thread, is);
3184 if (!is->read_tid) {
3185 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3193 static void stream_cycle_channel(VideoState *is, int codec_type)
3195 AVFormatContext *ic = is->ic;
3196 int start_index, stream_index;
3199 AVProgram *p = NULL;
3200 int nb_streams = is->ic->nb_streams;
3202 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3203 start_index = is->last_video_stream;
3204 old_index = is->video_stream;
3205 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3206 start_index = is->last_audio_stream;
3207 old_index = is->audio_stream;
3209 start_index = is->last_subtitle_stream;
3210 old_index = is->subtitle_stream;
3212 stream_index = start_index;
3214 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3215 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3217 nb_streams = p->nb_stream_indexes;
3218 for (start_index = 0; start_index < nb_streams; start_index++)
3219 if (p->stream_index[start_index] == stream_index)
3221 if (start_index == nb_streams)
3223 stream_index = start_index;
3228 if (++stream_index >= nb_streams)
3230 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3233 is->last_subtitle_stream = -1;
3236 if (start_index == -1)
3240 if (stream_index == start_index)
3242 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3243 if (st->codec->codec_type == codec_type) {
3244 /* check that parameters are OK */
3245 switch (codec_type) {
3246 case AVMEDIA_TYPE_AUDIO:
3247 if (st->codec->sample_rate != 0 &&
3248 st->codec->channels != 0)
3251 case AVMEDIA_TYPE_VIDEO:
3252 case AVMEDIA_TYPE_SUBTITLE:
3260 if (p && stream_index != -1)
3261 stream_index = p->stream_index[stream_index];
3262 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3263 av_get_media_type_string(codec_type),
3267 stream_component_close(is, old_index);
3268 stream_component_open(is, stream_index);
3272 static void toggle_full_screen(VideoState *is)
3274 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3275 /* OS X needs to reallocate the SDL overlays */
3277 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3278 is->pictq.queue[i].reallocate = 1;
3280 is_full_screen = !is_full_screen;
3281 video_open(is, 1, NULL);
3284 static void toggle_audio_display(VideoState *is)
3286 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3287 int next = is->show_mode;
3289 next = (next + 1) % SHOW_MODE_NB;
3290 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3291 if (is->show_mode != next) {
3292 fill_rectangle(screen,
3293 is->xleft, is->ytop, is->width, is->height,
3295 is->force_refresh = 1;
3296 is->show_mode = next;
3300 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3301 double remaining_time = 0.0;
3303 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3304 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3308 if (remaining_time > 0.0)
3309 av_usleep((int64_t)(remaining_time * 1000000.0));
3310 remaining_time = REFRESH_RATE;
3311 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3312 video_refresh(is, &remaining_time);
3317 static void seek_chapter(VideoState *is, int incr)
3319 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3322 if (!is->ic->nb_chapters)
3325 /* find the current chapter */
3326 for (i = 0; i < is->ic->nb_chapters; i++) {
3327 AVChapter *ch = is->ic->chapters[i];
3328 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3336 if (i >= is->ic->nb_chapters)
3339 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3340 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3341 AV_TIME_BASE_Q), 0, 0);
3344 /* handle an event sent by the GUI */
3345 static void event_loop(VideoState *cur_stream)
3348 double incr, pos, frac;
3352 refresh_loop_wait_event(cur_stream, &event);
3353 switch (event.type) {
3355 if (exit_on_keydown) {
3356 do_exit(cur_stream);
3359 switch (event.key.keysym.sym) {
3362 do_exit(cur_stream);
3365 toggle_full_screen(cur_stream);
3366 cur_stream->force_refresh = 1;
3370 toggle_pause(cur_stream);
3373 toggle_mute(cur_stream);
3375 case SDLK_KP_MULTIPLY:
3377 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3379 case SDLK_KP_DIVIDE:
3381 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3383 case SDLK_s: // S: Step to next frame
3384 step_to_next_frame(cur_stream);
3387 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3390 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3393 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3394 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3395 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3398 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3402 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3403 if (++cur_stream->vfilter_idx >= nb_vfilters)
3404 cur_stream->vfilter_idx = 0;
3406 cur_stream->vfilter_idx = 0;
3407 toggle_audio_display(cur_stream);
3410 toggle_audio_display(cur_stream);
3414 if (cur_stream->ic->nb_chapters <= 1) {
3418 seek_chapter(cur_stream, 1);
3421 if (cur_stream->ic->nb_chapters <= 1) {
3425 seek_chapter(cur_stream, -1);
3439 if (seek_by_bytes) {
3441 if (pos < 0 && cur_stream->video_stream >= 0)
3442 pos = frame_queue_last_pos(&cur_stream->pictq);
3443 if (pos < 0 && cur_stream->audio_stream >= 0)
3444 pos = frame_queue_last_pos(&cur_stream->sampq);
3446 pos = avio_tell(cur_stream->ic->pb);
3447 if (cur_stream->ic->bit_rate)
3448 incr *= cur_stream->ic->bit_rate / 8.0;
3452 stream_seek(cur_stream, pos, incr, 1);
3454 pos = get_master_clock(cur_stream);
3456 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3458 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3459 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3460 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3467 case SDL_VIDEOEXPOSE:
3468 cur_stream->force_refresh = 1;
3470 case SDL_MOUSEBUTTONDOWN:
3471 if (exit_on_mousedown) {
3472 do_exit(cur_stream);
3475 if (event.button.button == SDL_BUTTON_LEFT) {
3476 static int64_t last_mouse_left_click = 0;
3477 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3478 toggle_full_screen(cur_stream);
3479 cur_stream->force_refresh = 1;
3480 last_mouse_left_click = 0;
3482 last_mouse_left_click = av_gettime_relative();
3485 case SDL_MOUSEMOTION:
3486 if (cursor_hidden) {
3490 cursor_last_shown = av_gettime_relative();
3491 if (event.type == SDL_MOUSEBUTTONDOWN) {
3492 if (event.button.button != SDL_BUTTON_RIGHT)
3496 if (!(event.motion.state & SDL_BUTTON_RMASK))
3500 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3501 uint64_t size = avio_size(cur_stream->ic->pb);
3502 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3506 int tns, thh, tmm, tss;
3507 tns = cur_stream->ic->duration / 1000000LL;
3509 tmm = (tns % 3600) / 60;
3511 frac = x / cur_stream->width;
3514 mm = (ns % 3600) / 60;
3516 av_log(NULL, AV_LOG_INFO,
3517 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3518 hh, mm, ss, thh, tmm, tss);
3519 ts = frac * cur_stream->ic->duration;
3520 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3521 ts += cur_stream->ic->start_time;
3522 stream_seek(cur_stream, ts, 0, 0);
3525 case SDL_VIDEORESIZE:
3526 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3527 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3529 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3530 do_exit(cur_stream);
3532 screen_width = cur_stream->width = screen->w;
3533 screen_height = cur_stream->height = screen->h;
3534 cur_stream->force_refresh = 1;
3538 do_exit(cur_stream);
3540 case FF_ALLOC_EVENT:
3541 alloc_picture(event.user.data1);
3549 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3551 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3552 return opt_default(NULL, "video_size", arg);
3555 static int opt_width(void *optctx, const char *opt, const char *arg)
3557 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3561 static int opt_height(void *optctx, const char *opt, const char *arg)
3563 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3567 static int opt_format(void *optctx, const char *opt, const char *arg)
3569 file_iformat = av_find_input_format(arg);
3570 if (!file_iformat) {
3571 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3572 return AVERROR(EINVAL);
3577 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3579 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3580 return opt_default(NULL, "pixel_format", arg);
3583 static int opt_sync(void *optctx, const char *opt, const char *arg)
3585 if (!strcmp(arg, "audio"))
3586 av_sync_type = AV_SYNC_AUDIO_MASTER;
3587 else if (!strcmp(arg, "video"))
3588 av_sync_type = AV_SYNC_VIDEO_MASTER;
3589 else if (!strcmp(arg, "ext"))
3590 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3592 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3598 static int opt_seek(void *optctx, const char *opt, const char *arg)
3600 start_time = parse_time_or_die(opt, arg, 1);
3604 static int opt_duration(void *optctx, const char *opt, const char *arg)
3606 duration = parse_time_or_die(opt, arg, 1);
3610 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3612 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3613 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3614 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3615 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3619 static void opt_input_file(void *optctx, const char *filename)
3621 if (input_filename) {
3622 av_log(NULL, AV_LOG_FATAL,
3623 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3624 filename, input_filename);
3627 if (!strcmp(filename, "-"))
3629 input_filename = filename;
3632 static int opt_codec(void *optctx, const char *opt, const char *arg)
3634 const char *spec = strchr(opt, ':');
3636 av_log(NULL, AV_LOG_ERROR,
3637 "No media specifier was specified in '%s' in option '%s'\n",
3639 return AVERROR(EINVAL);
3643 case 'a' : audio_codec_name = arg; break;
3644 case 's' : subtitle_codec_name = arg; break;
3645 case 'v' : video_codec_name = arg; break;
3647 av_log(NULL, AV_LOG_ERROR,
3648 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3649 return AVERROR(EINVAL);
3656 static const OptionDef options[] = {
3657 #include "cmdutils_common_opts.h"
3658 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3659 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3660 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3661 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3662 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3663 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3664 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3665 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3666 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3667 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3668 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3669 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3670 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3671 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3672 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3673 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3674 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3675 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3676 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3677 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3678 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3679 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3680 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3681 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3682 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3683 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3684 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3685 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3686 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3688 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3689 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3691 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3692 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3693 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3694 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3695 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3696 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3697 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3698 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3699 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3703 static void show_usage(void)
3705 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3706 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3707 av_log(NULL, AV_LOG_INFO, "\n");
3710 void show_help_default(const char *opt, const char *arg)
3712 av_log_set_callback(log_callback_help);
3714 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3715 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3717 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3718 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3719 #if !CONFIG_AVFILTER
3720 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3722 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3724 printf("\nWhile playing:\n"
3726 "f toggle full screen\n"
3729 "9, 0 decrease and increase volume respectively\n"
3730 "/, * decrease and increase volume respectively\n"
3731 "a cycle audio channel in the current program\n"
3732 "v cycle video channel\n"
3733 "t cycle subtitle channel in the current program\n"
3735 "w cycle video filters or show modes\n"
3736 "s activate frame-step mode\n"
3737 "left/right seek backward/forward 10 seconds\n"
3738 "down/up seek backward/forward 1 minute\n"
3739 "page down/page up seek backward/forward 10 minutes\n"
3740 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3741 "left double-click toggle full screen\n"
3745 static int lockmgr(void **mtx, enum AVLockOp op)
3748 case AV_LOCK_CREATE:
3749 *mtx = SDL_CreateMutex();
3751 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3755 case AV_LOCK_OBTAIN:
3756 return !!SDL_LockMutex(*mtx);
3757 case AV_LOCK_RELEASE:
3758 return !!SDL_UnlockMutex(*mtx);
3759 case AV_LOCK_DESTROY:
3760 SDL_DestroyMutex(*mtx);
3766 /* Called from the main */
3767 int main(int argc, char **argv)
3771 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3773 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3774 parse_loglevel(argc, argv, options);
3776 /* register all codecs, demux and protocols */
3778 avdevice_register_all();
3781 avfilter_register_all();
3784 avformat_network_init();
3788 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3789 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3791 show_banner(argc, argv, options);
3793 parse_options(NULL, argc, argv, options, opt_input_file);
3795 if (!input_filename) {
3797 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3798 av_log(NULL, AV_LOG_FATAL,
3799 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3803 if (display_disable) {
3806 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3808 flags &= ~SDL_INIT_AUDIO;
3809 if (display_disable)
3810 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3811 #if !defined(_WIN32) && !defined(__APPLE__)
3812 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3814 if (SDL_Init (flags)) {
3815 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3816 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3820 if (!display_disable) {
3821 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3822 fs_screen_width = vi->current_w;
3823 fs_screen_height = vi->current_h;
3826 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3827 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3828 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3830 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3832 if (av_lockmgr_register(lockmgr)) {
3833 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3837 av_init_packet(&flush_pkt);
3838 flush_pkt.data = (uint8_t *)&flush_pkt;
3840 is = stream_open(input_filename, file_iformat);
3842 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");