2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 static unsigned sws_flags = SWS_BICUBIC;
110 typedef struct MyAVPacketList {
112 struct MyAVPacketList *next;
116 typedef struct PacketQueue {
117 MyAVPacketList *first_pkt, *last_pkt;
126 #define VIDEO_PICTURE_QUEUE_SIZE 3
127 #define SUBPICTURE_QUEUE_SIZE 16
128 #define SAMPLE_QUEUE_SIZE 9
129 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
131 typedef struct AudioParams {
134 int64_t channel_layout;
135 enum AVSampleFormat fmt;
140 typedef struct Clock {
141 double pts; /* clock base */
142 double pts_drift; /* clock base minus time at which we updated the clock */
145 int serial; /* clock is based on a packet with this serial */
147 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
150 /* Common struct for handling all types of decoded data and allocated render buffers. */
151 typedef struct Frame {
154 AVSubtitleRect **subrects; /* rescaled subtitle rectangles in yuva */
156 double pts; /* presentation timestamp for the frame */
157 double duration; /* estimated duration of the frame */
158 int64_t pos; /* byte position of the frame in the input file */
167 typedef struct FrameQueue {
168 Frame queue[FRAME_QUEUE_SIZE];
181 AV_SYNC_AUDIO_MASTER, /* default choice */
182 AV_SYNC_VIDEO_MASTER,
183 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
186 typedef struct Decoder {
190 AVCodecContext *avctx;
194 SDL_cond *empty_queue_cond;
196 AVRational start_pts_tb;
198 AVRational next_pts_tb;
199 SDL_Thread *decoder_tid;
202 typedef struct VideoState {
203 SDL_Thread *read_tid;
204 AVInputFormat *iformat;
209 int queue_attachments_req;
214 int read_pause_return;
238 int audio_clock_serial;
239 double audio_diff_cum; /* used for AV difference average computation */
240 double audio_diff_avg_coef;
241 double audio_diff_threshold;
242 int audio_diff_avg_count;
245 int audio_hw_buf_size;
246 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
249 unsigned int audio_buf_size; /* in bytes */
250 unsigned int audio_buf1_size;
251 int audio_buf_index; /* in bytes */
252 int audio_write_buf_size;
255 struct AudioParams audio_src;
257 struct AudioParams audio_filter_src;
259 struct AudioParams audio_tgt;
260 struct SwrContext *swr_ctx;
261 int frame_drops_early;
262 int frame_drops_late;
265 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
267 int16_t sample_array[SAMPLE_ARRAY_SIZE];
268 int sample_array_index;
272 FFTSample *rdft_data;
274 double last_vis_time;
277 AVStream *subtitle_st;
278 PacketQueue subtitleq;
281 double frame_last_returned_time;
282 double frame_last_filter_delay;
286 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
288 struct SwsContext *img_convert_ctx;
290 struct SwsContext *sub_convert_ctx;
291 SDL_Rect last_display_rect;
295 int width, height, xleft, ytop;
300 AVFilterContext *in_video_filter; // the first filter in the video chain
301 AVFilterContext *out_video_filter; // the last filter in the video chain
302 AVFilterContext *in_audio_filter; // the first filter in the audio chain
303 AVFilterContext *out_audio_filter; // the last filter in the audio chain
304 AVFilterGraph *agraph; // audio filter graph
307 int last_video_stream, last_audio_stream, last_subtitle_stream;
309 SDL_cond *continue_read_thread;
312 /* options specified by the user */
313 static AVInputFormat *file_iformat;
314 static const char *input_filename;
315 static const char *window_title;
316 static int fs_screen_width;
317 static int fs_screen_height;
318 static int default_width = 640;
319 static int default_height = 480;
320 static int screen_width = 0;
321 static int screen_height = 0;
322 static int audio_disable;
323 static int video_disable;
324 static int subtitle_disable;
325 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
326 static int seek_by_bytes = -1;
327 static int display_disable;
328 static int show_status = 1;
329 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
330 static int64_t start_time = AV_NOPTS_VALUE;
331 static int64_t duration = AV_NOPTS_VALUE;
333 static int genpts = 0;
334 static int lowres = 0;
335 static int decoder_reorder_pts = -1;
337 static int exit_on_keydown;
338 static int exit_on_mousedown;
340 static int framedrop = -1;
341 static int infinite_buffer = -1;
342 static enum ShowMode show_mode = SHOW_MODE_NONE;
343 static const char *audio_codec_name;
344 static const char *subtitle_codec_name;
345 static const char *video_codec_name;
346 double rdftspeed = 0.02;
347 static int64_t cursor_last_shown;
348 static int cursor_hidden = 0;
350 static const char **vfilters_list = NULL;
351 static int nb_vfilters = 0;
352 static char *afilters = NULL;
354 static int autorotate = 1;
356 /* current context */
357 static int is_full_screen;
358 static int64_t audio_callback_time;
360 static AVPacket flush_pkt;
362 #define FF_ALLOC_EVENT (SDL_USEREVENT)
363 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
365 static SDL_Surface *screen;
368 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
370 GROW_ARRAY(vfilters_list, nb_vfilters);
371 vfilters_list[nb_vfilters - 1] = arg;
377 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
378 enum AVSampleFormat fmt2, int64_t channel_count2)
380 /* If channel count == 1, planar and non-planar formats are the same */
381 if (channel_count1 == 1 && channel_count2 == 1)
382 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
384 return channel_count1 != channel_count2 || fmt1 != fmt2;
388 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
390 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
391 return channel_layout;
396 static void free_picture(Frame *vp);
398 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
400 MyAVPacketList *pkt1;
402 if (q->abort_request)
405 pkt1 = av_malloc(sizeof(MyAVPacketList));
410 if (pkt == &flush_pkt)
412 pkt1->serial = q->serial;
417 q->last_pkt->next = pkt1;
420 q->size += pkt1->pkt.size + sizeof(*pkt1);
421 /* XXX: should duplicate packet data in DV case */
422 SDL_CondSignal(q->cond);
426 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
430 SDL_LockMutex(q->mutex);
431 ret = packet_queue_put_private(q, pkt);
432 SDL_UnlockMutex(q->mutex);
434 if (pkt != &flush_pkt && ret < 0)
435 av_packet_unref(pkt);
440 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
442 AVPacket pkt1, *pkt = &pkt1;
446 pkt->stream_index = stream_index;
447 return packet_queue_put(q, pkt);
450 /* packet queue handling */
451 static int packet_queue_init(PacketQueue *q)
453 memset(q, 0, sizeof(PacketQueue));
454 q->mutex = SDL_CreateMutex();
456 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
457 return AVERROR(ENOMEM);
459 q->cond = SDL_CreateCond();
461 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
462 return AVERROR(ENOMEM);
464 q->abort_request = 1;
468 static void packet_queue_flush(PacketQueue *q)
470 MyAVPacketList *pkt, *pkt1;
472 SDL_LockMutex(q->mutex);
473 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
475 av_packet_unref(&pkt->pkt);
482 SDL_UnlockMutex(q->mutex);
485 static void packet_queue_destroy(PacketQueue *q)
487 packet_queue_flush(q);
488 SDL_DestroyMutex(q->mutex);
489 SDL_DestroyCond(q->cond);
492 static void packet_queue_abort(PacketQueue *q)
494 SDL_LockMutex(q->mutex);
496 q->abort_request = 1;
498 SDL_CondSignal(q->cond);
500 SDL_UnlockMutex(q->mutex);
503 static void packet_queue_start(PacketQueue *q)
505 SDL_LockMutex(q->mutex);
506 q->abort_request = 0;
507 packet_queue_put_private(q, &flush_pkt);
508 SDL_UnlockMutex(q->mutex);
511 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
512 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
514 MyAVPacketList *pkt1;
517 SDL_LockMutex(q->mutex);
520 if (q->abort_request) {
527 q->first_pkt = pkt1->next;
531 q->size -= pkt1->pkt.size + sizeof(*pkt1);
534 *serial = pkt1->serial;
542 SDL_CondWait(q->cond, q->mutex);
545 SDL_UnlockMutex(q->mutex);
549 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
550 memset(d, 0, sizeof(Decoder));
553 d->empty_queue_cond = empty_queue_cond;
554 d->start_pts = AV_NOPTS_VALUE;
557 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
563 if (d->queue->abort_request)
566 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
569 if (d->queue->nb_packets == 0)
570 SDL_CondSignal(d->empty_queue_cond);
571 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
573 if (pkt.data == flush_pkt.data) {
574 avcodec_flush_buffers(d->avctx);
576 d->next_pts = d->start_pts;
577 d->next_pts_tb = d->start_pts_tb;
579 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
580 av_packet_unref(&d->pkt);
581 d->pkt_temp = d->pkt = pkt;
582 d->packet_pending = 1;
585 switch (d->avctx->codec_type) {
586 case AVMEDIA_TYPE_VIDEO:
587 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
589 if (decoder_reorder_pts == -1) {
590 frame->pts = av_frame_get_best_effort_timestamp(frame);
591 } else if (decoder_reorder_pts) {
592 frame->pts = frame->pkt_pts;
594 frame->pts = frame->pkt_dts;
598 case AVMEDIA_TYPE_AUDIO:
599 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
601 AVRational tb = (AVRational){1, frame->sample_rate};
602 if (frame->pts != AV_NOPTS_VALUE)
603 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
604 else if (frame->pkt_pts != AV_NOPTS_VALUE)
605 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
606 else if (d->next_pts != AV_NOPTS_VALUE)
607 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
608 if (frame->pts != AV_NOPTS_VALUE) {
609 d->next_pts = frame->pts + frame->nb_samples;
614 case AVMEDIA_TYPE_SUBTITLE:
615 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
620 d->packet_pending = 0;
623 d->pkt_temp.pts = AV_NOPTS_VALUE;
624 if (d->pkt_temp.data) {
625 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
626 ret = d->pkt_temp.size;
627 d->pkt_temp.data += ret;
628 d->pkt_temp.size -= ret;
629 if (d->pkt_temp.size <= 0)
630 d->packet_pending = 0;
633 d->packet_pending = 0;
634 d->finished = d->pkt_serial;
638 } while (!got_frame && !d->finished);
643 static void decoder_destroy(Decoder *d) {
644 av_packet_unref(&d->pkt);
647 static void frame_queue_unref_item(Frame *vp)
650 for (i = 0; i < vp->sub.num_rects; i++) {
651 av_freep(&vp->subrects[i]->data[0]);
652 av_freep(&vp->subrects[i]);
654 av_freep(&vp->subrects);
655 av_frame_unref(vp->frame);
656 avsubtitle_free(&vp->sub);
659 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
662 memset(f, 0, sizeof(FrameQueue));
663 if (!(f->mutex = SDL_CreateMutex())) {
664 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
665 return AVERROR(ENOMEM);
667 if (!(f->cond = SDL_CreateCond())) {
668 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
669 return AVERROR(ENOMEM);
672 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
673 f->keep_last = !!keep_last;
674 for (i = 0; i < f->max_size; i++)
675 if (!(f->queue[i].frame = av_frame_alloc()))
676 return AVERROR(ENOMEM);
680 static void frame_queue_destory(FrameQueue *f)
683 for (i = 0; i < f->max_size; i++) {
684 Frame *vp = &f->queue[i];
685 frame_queue_unref_item(vp);
686 av_frame_free(&vp->frame);
689 SDL_DestroyMutex(f->mutex);
690 SDL_DestroyCond(f->cond);
693 static void frame_queue_signal(FrameQueue *f)
695 SDL_LockMutex(f->mutex);
696 SDL_CondSignal(f->cond);
697 SDL_UnlockMutex(f->mutex);
700 static Frame *frame_queue_peek(FrameQueue *f)
702 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
705 static Frame *frame_queue_peek_next(FrameQueue *f)
707 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
710 static Frame *frame_queue_peek_last(FrameQueue *f)
712 return &f->queue[f->rindex];
715 static Frame *frame_queue_peek_writable(FrameQueue *f)
717 /* wait until we have space to put a new frame */
718 SDL_LockMutex(f->mutex);
719 while (f->size >= f->max_size &&
720 !f->pktq->abort_request) {
721 SDL_CondWait(f->cond, f->mutex);
723 SDL_UnlockMutex(f->mutex);
725 if (f->pktq->abort_request)
728 return &f->queue[f->windex];
731 static Frame *frame_queue_peek_readable(FrameQueue *f)
733 /* wait until we have a readable a new frame */
734 SDL_LockMutex(f->mutex);
735 while (f->size - f->rindex_shown <= 0 &&
736 !f->pktq->abort_request) {
737 SDL_CondWait(f->cond, f->mutex);
739 SDL_UnlockMutex(f->mutex);
741 if (f->pktq->abort_request)
744 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
747 static void frame_queue_push(FrameQueue *f)
749 if (++f->windex == f->max_size)
751 SDL_LockMutex(f->mutex);
753 SDL_CondSignal(f->cond);
754 SDL_UnlockMutex(f->mutex);
757 static void frame_queue_next(FrameQueue *f)
759 if (f->keep_last && !f->rindex_shown) {
763 frame_queue_unref_item(&f->queue[f->rindex]);
764 if (++f->rindex == f->max_size)
766 SDL_LockMutex(f->mutex);
768 SDL_CondSignal(f->cond);
769 SDL_UnlockMutex(f->mutex);
772 /* jump back to the previous frame if available by resetting rindex_shown */
773 static int frame_queue_prev(FrameQueue *f)
775 int ret = f->rindex_shown;
780 /* return the number of undisplayed frames in the queue */
781 static int frame_queue_nb_remaining(FrameQueue *f)
783 return f->size - f->rindex_shown;
786 /* return last shown position */
787 static int64_t frame_queue_last_pos(FrameQueue *f)
789 Frame *fp = &f->queue[f->rindex];
790 if (f->rindex_shown && fp->serial == f->pktq->serial)
796 static void decoder_abort(Decoder *d, FrameQueue *fq)
798 packet_queue_abort(d->queue);
799 frame_queue_signal(fq);
800 SDL_WaitThread(d->decoder_tid, NULL);
801 d->decoder_tid = NULL;
802 packet_queue_flush(d->queue);
805 static inline void fill_rectangle(SDL_Surface *screen,
806 int x, int y, int w, int h, int color, int update)
813 SDL_FillRect(screen, &rect, color);
814 if (update && w > 0 && h > 0)
815 SDL_UpdateRect(screen, x, y, w, h);
818 /* draw only the border of a rectangle */
819 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
823 /* fill the background */
827 w2 = width - (x + w);
833 h2 = height - (y + h);
836 fill_rectangle(screen,
840 fill_rectangle(screen,
841 xleft + width - w2, ytop,
844 fill_rectangle(screen,
848 fill_rectangle(screen,
849 xleft + w1, ytop + height - h2,
854 #define ALPHA_BLEND(a, oldp, newp, s)\
855 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
861 static void blend_subrect(uint8_t **data, int *linesize, const AVSubtitleRect *rect, int imgw, int imgh)
863 int x, y, Y, U, V, A;
864 uint8_t *lum, *cb, *cr;
865 int dstx, dsty, dstw, dsth;
866 const AVSubtitleRect *src = rect;
868 dstw = av_clip(rect->w, 0, imgw);
869 dsth = av_clip(rect->h, 0, imgh);
870 dstx = av_clip(rect->x, 0, imgw - dstw);
871 dsty = av_clip(rect->y, 0, imgh - dsth);
872 lum = data[0] + dstx + dsty * linesize[0];
873 cb = data[1] + dstx/2 + (dsty >> 1) * linesize[1];
874 cr = data[2] + dstx/2 + (dsty >> 1) * linesize[2];
876 for (y = 0; y<dsth; y++) {
877 for (x = 0; x<dstw; x++) {
878 Y = src->data[0][x + y*src->linesize[0]];
879 A = src->data[3][x + y*src->linesize[3]];
880 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
883 lum += linesize[0] - dstw;
886 for (y = 0; y<dsth/2; y++) {
887 for (x = 0; x<dstw/2; x++) {
888 U = src->data[1][x + y*src->linesize[1]];
889 V = src->data[2][x + y*src->linesize[2]];
890 A = src->data[3][2*x + 2*y *src->linesize[3]]
891 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
892 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
893 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
894 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
895 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
899 cb += linesize[1] - dstw/2;
900 cr += linesize[2] - dstw/2;
904 static void free_picture(Frame *vp)
907 SDL_FreeYUVOverlay(vp->bmp);
912 static void calculate_display_rect(SDL_Rect *rect,
913 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
914 int pic_width, int pic_height, AVRational pic_sar)
917 int width, height, x, y;
919 if (pic_sar.num == 0)
922 aspect_ratio = av_q2d(pic_sar);
924 if (aspect_ratio <= 0.0)
926 aspect_ratio *= (float)pic_width / (float)pic_height;
928 /* XXX: we suppose the screen has a 1.0 pixel ratio */
930 width = lrint(height * aspect_ratio) & ~1;
931 if (width > scr_width) {
933 height = lrint(width / aspect_ratio) & ~1;
935 x = (scr_width - width) / 2;
936 y = (scr_height - height) / 2;
937 rect->x = scr_xleft + x;
938 rect->y = scr_ytop + y;
939 rect->w = FFMAX(width, 1);
940 rect->h = FFMAX(height, 1);
943 static void video_image_display(VideoState *is)
950 vp = frame_queue_peek(&is->pictq);
952 if (is->subtitle_st) {
953 if (frame_queue_nb_remaining(&is->subpq) > 0) {
954 sp = frame_queue_peek(&is->subpq);
956 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
960 SDL_LockYUVOverlay (vp->bmp);
962 data[0] = vp->bmp->pixels[0];
963 data[1] = vp->bmp->pixels[2];
964 data[2] = vp->bmp->pixels[1];
966 linesize[0] = vp->bmp->pitches[0];
967 linesize[1] = vp->bmp->pitches[2];
968 linesize[2] = vp->bmp->pitches[1];
970 for (i = 0; i < sp->sub.num_rects; i++)
971 blend_subrect(data, linesize, sp->subrects[i],
972 vp->bmp->w, vp->bmp->h);
974 SDL_UnlockYUVOverlay (vp->bmp);
979 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
981 SDL_DisplayYUVOverlay(vp->bmp, &rect);
983 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) {
984 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
985 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
986 is->last_display_rect = rect;
991 static inline int compute_mod(int a, int b)
993 return a < 0 ? a%b + b : a%b;
996 static void video_audio_display(VideoState *s)
998 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
999 int ch, channels, h, h2, bgcolor, fgcolor;
1001 int rdft_bits, nb_freq;
1003 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1005 nb_freq = 1 << (rdft_bits - 1);
1007 /* compute display index : center on currently output samples */
1008 channels = s->audio_tgt.channels;
1009 nb_display_channels = channels;
1011 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1013 delay = s->audio_write_buf_size;
1016 /* to be more precise, we take into account the time spent since
1017 the last buffer computation */
1018 if (audio_callback_time) {
1019 time_diff = av_gettime_relative() - audio_callback_time;
1020 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1023 delay += 2 * data_used;
1024 if (delay < data_used)
1027 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1028 if (s->show_mode == SHOW_MODE_WAVES) {
1030 for (i = 0; i < 1000; i += channels) {
1031 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1032 int a = s->sample_array[idx];
1033 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1034 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1035 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1037 if (h < score && (b ^ c) < 0) {
1044 s->last_i_start = i_start;
1046 i_start = s->last_i_start;
1049 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1050 if (s->show_mode == SHOW_MODE_WAVES) {
1051 fill_rectangle(screen,
1052 s->xleft, s->ytop, s->width, s->height,
1055 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1057 /* total height for one channel */
1058 h = s->height / nb_display_channels;
1059 /* graph height / 2 */
1061 for (ch = 0; ch < nb_display_channels; ch++) {
1063 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1064 for (x = 0; x < s->width; x++) {
1065 y = (s->sample_array[i] * h2) >> 15;
1072 fill_rectangle(screen,
1073 s->xleft + x, ys, 1, y,
1076 if (i >= SAMPLE_ARRAY_SIZE)
1077 i -= SAMPLE_ARRAY_SIZE;
1081 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1083 for (ch = 1; ch < nb_display_channels; ch++) {
1084 y = s->ytop + ch * h;
1085 fill_rectangle(screen,
1086 s->xleft, y, s->width, 1,
1089 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1091 nb_display_channels= FFMIN(nb_display_channels, 2);
1092 if (rdft_bits != s->rdft_bits) {
1093 av_rdft_end(s->rdft);
1094 av_free(s->rdft_data);
1095 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1096 s->rdft_bits = rdft_bits;
1097 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1099 if (!s->rdft || !s->rdft_data){
1100 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1101 s->show_mode = SHOW_MODE_WAVES;
1104 for (ch = 0; ch < nb_display_channels; ch++) {
1105 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1107 for (x = 0; x < 2 * nb_freq; x++) {
1108 double w = (x-nb_freq) * (1.0 / nb_freq);
1109 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1111 if (i >= SAMPLE_ARRAY_SIZE)
1112 i -= SAMPLE_ARRAY_SIZE;
1114 av_rdft_calc(s->rdft, data[ch]);
1116 /* Least efficient way to do this, we should of course
1117 * directly access it but it is more than fast enough. */
1118 for (y = 0; y < s->height; y++) {
1119 double w = 1 / sqrt(nb_freq);
1120 int a = sqrt(w * hypot(data[0][2 * y + 0], data[0][2 * y + 1]));
1121 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1125 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1127 fill_rectangle(screen,
1128 s->xpos, s->height-y, 1, 1,
1132 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1135 if (s->xpos >= s->width)
1140 static void stream_component_close(VideoState *is, int stream_index)
1142 AVFormatContext *ic = is->ic;
1143 AVCodecContext *avctx;
1145 if (stream_index < 0 || stream_index >= ic->nb_streams)
1147 avctx = ic->streams[stream_index]->codec;
1149 switch (avctx->codec_type) {
1150 case AVMEDIA_TYPE_AUDIO:
1151 decoder_abort(&is->auddec, &is->sampq);
1153 decoder_destroy(&is->auddec);
1154 swr_free(&is->swr_ctx);
1155 av_freep(&is->audio_buf1);
1156 is->audio_buf1_size = 0;
1157 is->audio_buf = NULL;
1160 av_rdft_end(is->rdft);
1161 av_freep(&is->rdft_data);
1166 case AVMEDIA_TYPE_VIDEO:
1167 decoder_abort(&is->viddec, &is->pictq);
1168 decoder_destroy(&is->viddec);
1170 case AVMEDIA_TYPE_SUBTITLE:
1171 decoder_abort(&is->subdec, &is->subpq);
1172 decoder_destroy(&is->subdec);
1178 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1179 avcodec_close(avctx);
1180 switch (avctx->codec_type) {
1181 case AVMEDIA_TYPE_AUDIO:
1182 is->audio_st = NULL;
1183 is->audio_stream = -1;
1185 case AVMEDIA_TYPE_VIDEO:
1186 is->video_st = NULL;
1187 is->video_stream = -1;
1189 case AVMEDIA_TYPE_SUBTITLE:
1190 is->subtitle_st = NULL;
1191 is->subtitle_stream = -1;
1198 static void stream_close(VideoState *is)
1200 /* XXX: use a special url_shutdown call to abort parse cleanly */
1201 is->abort_request = 1;
1202 SDL_WaitThread(is->read_tid, NULL);
1204 /* close each stream */
1205 if (is->audio_stream >= 0)
1206 stream_component_close(is, is->audio_stream);
1207 if (is->video_stream >= 0)
1208 stream_component_close(is, is->video_stream);
1209 if (is->subtitle_stream >= 0)
1210 stream_component_close(is, is->subtitle_stream);
1212 avformat_close_input(&is->ic);
1214 packet_queue_destroy(&is->videoq);
1215 packet_queue_destroy(&is->audioq);
1216 packet_queue_destroy(&is->subtitleq);
1218 /* free all pictures */
1219 frame_queue_destory(&is->pictq);
1220 frame_queue_destory(&is->sampq);
1221 frame_queue_destory(&is->subpq);
1222 SDL_DestroyCond(is->continue_read_thread);
1223 #if !CONFIG_AVFILTER
1224 sws_freeContext(is->img_convert_ctx);
1226 sws_freeContext(is->sub_convert_ctx);
1227 av_free(is->filename);
1231 static void do_exit(VideoState *is)
1236 av_lockmgr_register(NULL);
1239 av_freep(&vfilters_list);
1241 avformat_network_deinit();
1245 av_log(NULL, AV_LOG_QUIET, "%s", "");
1249 static void sigterm_handler(int sig)
1254 static void set_default_window_size(int width, int height, AVRational sar)
1257 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1258 default_width = rect.w;
1259 default_height = rect.h;
1262 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1264 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1267 if (is_full_screen) flags |= SDL_FULLSCREEN;
1268 else flags |= SDL_RESIZABLE;
1270 if (vp && vp->width)
1271 set_default_window_size(vp->width, vp->height, vp->sar);
1273 if (is_full_screen && fs_screen_width) {
1274 w = fs_screen_width;
1275 h = fs_screen_height;
1276 } else if (!is_full_screen && screen_width) {
1283 w = FFMIN(16383, w);
1284 if (screen && is->width == screen->w && screen->w == w
1285 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1287 screen = SDL_SetVideoMode(w, h, 0, flags);
1289 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1293 window_title = input_filename;
1294 SDL_WM_SetCaption(window_title, window_title);
1296 is->width = screen->w;
1297 is->height = screen->h;
1302 /* display the current picture, if any */
1303 static void video_display(VideoState *is)
1306 video_open(is, 0, NULL);
1307 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1308 video_audio_display(is);
1309 else if (is->video_st)
1310 video_image_display(is);
1313 static double get_clock(Clock *c)
1315 if (*c->queue_serial != c->serial)
1320 double time = av_gettime_relative() / 1000000.0;
1321 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1325 static void set_clock_at(Clock *c, double pts, int serial, double time)
1328 c->last_updated = time;
1329 c->pts_drift = c->pts - time;
1333 static void set_clock(Clock *c, double pts, int serial)
1335 double time = av_gettime_relative() / 1000000.0;
1336 set_clock_at(c, pts, serial, time);
1339 static void set_clock_speed(Clock *c, double speed)
1341 set_clock(c, get_clock(c), c->serial);
1345 static void init_clock(Clock *c, int *queue_serial)
1349 c->queue_serial = queue_serial;
1350 set_clock(c, NAN, -1);
1353 static void sync_clock_to_slave(Clock *c, Clock *slave)
1355 double clock = get_clock(c);
1356 double slave_clock = get_clock(slave);
1357 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1358 set_clock(c, slave_clock, slave->serial);
1361 static int get_master_sync_type(VideoState *is) {
1362 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1364 return AV_SYNC_VIDEO_MASTER;
1366 return AV_SYNC_AUDIO_MASTER;
1367 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1369 return AV_SYNC_AUDIO_MASTER;
1371 return AV_SYNC_EXTERNAL_CLOCK;
1373 return AV_SYNC_EXTERNAL_CLOCK;
1377 /* get the current master clock value */
1378 static double get_master_clock(VideoState *is)
1382 switch (get_master_sync_type(is)) {
1383 case AV_SYNC_VIDEO_MASTER:
1384 val = get_clock(&is->vidclk);
1386 case AV_SYNC_AUDIO_MASTER:
1387 val = get_clock(&is->audclk);
1390 val = get_clock(&is->extclk);
1396 static void check_external_clock_speed(VideoState *is) {
1397 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1398 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1399 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1400 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1401 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1402 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1404 double speed = is->extclk.speed;
1406 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1410 /* seek in the stream */
1411 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1413 if (!is->seek_req) {
1416 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1418 is->seek_flags |= AVSEEK_FLAG_BYTE;
1420 SDL_CondSignal(is->continue_read_thread);
1424 /* pause or resume the video */
1425 static void stream_toggle_pause(VideoState *is)
1428 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1429 if (is->read_pause_return != AVERROR(ENOSYS)) {
1430 is->vidclk.paused = 0;
1432 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1434 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1435 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1438 static void toggle_pause(VideoState *is)
1440 stream_toggle_pause(is);
1444 static void toggle_mute(VideoState *is)
1446 is->muted = !is->muted;
1449 static void update_volume(VideoState *is, int sign, int step)
1451 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1454 static void step_to_next_frame(VideoState *is)
1456 /* if the stream is paused unpause it, then step */
1458 stream_toggle_pause(is);
1462 static double compute_target_delay(double delay, VideoState *is)
1464 double sync_threshold, diff = 0;
1466 /* update delay to follow master synchronisation source */
1467 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1468 /* if video is slave, we try to correct big delays by
1469 duplicating or deleting a frame */
1470 diff = get_clock(&is->vidclk) - get_master_clock(is);
1472 /* skip or repeat frame. We take into account the
1473 delay to compute the threshold. I still don't know
1474 if it is the best guess */
1475 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1476 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1477 if (diff <= -sync_threshold)
1478 delay = FFMAX(0, delay + diff);
1479 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1480 delay = delay + diff;
1481 else if (diff >= sync_threshold)
1486 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1492 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1493 if (vp->serial == nextvp->serial) {
1494 double duration = nextvp->pts - vp->pts;
1495 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1496 return vp->duration;
1504 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1505 /* update current video pts */
1506 set_clock(&is->vidclk, pts, serial);
1507 sync_clock_to_slave(&is->extclk, &is->vidclk);
1510 /* called to display each frame */
1511 static void video_refresh(void *opaque, double *remaining_time)
1513 VideoState *is = opaque;
1518 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1519 check_external_clock_speed(is);
1521 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1522 time = av_gettime_relative() / 1000000.0;
1523 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1525 is->last_vis_time = time;
1527 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1532 if (is->force_refresh)
1533 redisplay = frame_queue_prev(&is->pictq);
1535 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1536 // nothing to do, no picture to display in the queue
1538 double last_duration, duration, delay;
1541 /* dequeue the picture */
1542 lastvp = frame_queue_peek_last(&is->pictq);
1543 vp = frame_queue_peek(&is->pictq);
1545 if (vp->serial != is->videoq.serial) {
1546 frame_queue_next(&is->pictq);
1551 if (lastvp->serial != vp->serial && !redisplay)
1552 is->frame_timer = av_gettime_relative() / 1000000.0;
1557 /* compute nominal last_duration */
1558 last_duration = vp_duration(is, lastvp, vp);
1562 delay = compute_target_delay(last_duration, is);
1564 time= av_gettime_relative()/1000000.0;
1565 if (time < is->frame_timer + delay && !redisplay) {
1566 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1570 is->frame_timer += delay;
1571 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1572 is->frame_timer = time;
1574 SDL_LockMutex(is->pictq.mutex);
1575 if (!redisplay && !isnan(vp->pts))
1576 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1577 SDL_UnlockMutex(is->pictq.mutex);
1579 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1580 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1581 duration = vp_duration(is, vp, nextvp);
1582 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1584 is->frame_drops_late++;
1585 frame_queue_next(&is->pictq);
1591 if (is->subtitle_st) {
1592 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1593 sp = frame_queue_peek(&is->subpq);
1595 if (frame_queue_nb_remaining(&is->subpq) > 1)
1596 sp2 = frame_queue_peek_next(&is->subpq);
1600 if (sp->serial != is->subtitleq.serial
1601 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1602 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1604 frame_queue_next(&is->subpq);
1612 /* display picture */
1613 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1616 frame_queue_next(&is->pictq);
1618 if (is->step && !is->paused)
1619 stream_toggle_pause(is);
1622 is->force_refresh = 0;
1624 static int64_t last_time;
1626 int aqsize, vqsize, sqsize;
1629 cur_time = av_gettime_relative();
1630 if (!last_time || (cur_time - last_time) >= 30000) {
1635 aqsize = is->audioq.size;
1637 vqsize = is->videoq.size;
1638 if (is->subtitle_st)
1639 sqsize = is->subtitleq.size;
1641 if (is->audio_st && is->video_st)
1642 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1643 else if (is->video_st)
1644 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1645 else if (is->audio_st)
1646 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1647 av_log(NULL, AV_LOG_INFO,
1648 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1649 get_master_clock(is),
1650 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1652 is->frame_drops_early + is->frame_drops_late,
1656 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1657 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1659 last_time = cur_time;
1664 /* allocate a picture (needs to do that in main thread to avoid
1665 potential locking problems */
1666 static void alloc_picture(VideoState *is)
1671 vp = &is->pictq.queue[is->pictq.windex];
1675 video_open(is, 0, vp);
1677 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1680 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1681 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1682 /* SDL allocates a buffer smaller than requested if the video
1683 * overlay hardware is unable to support the requested size. */
1684 av_log(NULL, AV_LOG_FATAL,
1685 "Error: the video system does not support an image\n"
1686 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1687 "to reduce the image size.\n", vp->width, vp->height );
1691 SDL_LockMutex(is->pictq.mutex);
1693 SDL_CondSignal(is->pictq.cond);
1694 SDL_UnlockMutex(is->pictq.mutex);
1697 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1698 int i, width, height;
1700 for (i = 0; i < 3; i++) {
1707 if (bmp->pitches[i] > width) {
1708 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1709 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1715 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1719 #if defined(DEBUG_SYNC) && 0
1720 printf("frame_type=%c pts=%0.3f\n",
1721 av_get_picture_type_char(src_frame->pict_type), pts);
1724 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1727 vp->sar = src_frame->sample_aspect_ratio;
1729 /* alloc or resize hardware picture buffer */
1730 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1731 vp->width != src_frame->width ||
1732 vp->height != src_frame->height) {
1737 vp->width = src_frame->width;
1738 vp->height = src_frame->height;
1740 /* the allocation must be done in the main thread to avoid
1741 locking problems. */
1742 event.type = FF_ALLOC_EVENT;
1743 event.user.data1 = is;
1744 SDL_PushEvent(&event);
1746 /* wait until the picture is allocated */
1747 SDL_LockMutex(is->pictq.mutex);
1748 while (!vp->allocated && !is->videoq.abort_request) {
1749 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1751 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1752 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1753 while (!vp->allocated && !is->abort_request) {
1754 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1757 SDL_UnlockMutex(is->pictq.mutex);
1759 if (is->videoq.abort_request)
1763 /* if the frame is not skipped, then display it */
1768 /* get a pointer on the bitmap */
1769 SDL_LockYUVOverlay (vp->bmp);
1771 data[0] = vp->bmp->pixels[0];
1772 data[1] = vp->bmp->pixels[2];
1773 data[2] = vp->bmp->pixels[1];
1775 linesize[0] = vp->bmp->pitches[0];
1776 linesize[1] = vp->bmp->pitches[2];
1777 linesize[2] = vp->bmp->pitches[1];
1780 // FIXME use direct rendering
1781 av_image_copy(data, linesize, (const uint8_t **)src_frame->data, src_frame->linesize,
1782 src_frame->format, vp->width, vp->height);
1785 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1787 const AVClass *class = sws_get_class();
1788 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1789 AV_OPT_SEARCH_FAKE_OBJ);
1790 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1796 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1797 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1798 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1799 if (!is->img_convert_ctx) {
1800 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1803 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1804 0, vp->height, data, linesize);
1806 /* workaround SDL PITCH_WORKAROUND */
1807 duplicate_right_border_pixels(vp->bmp);
1808 /* update the bitmap content */
1809 SDL_UnlockYUVOverlay(vp->bmp);
1812 vp->duration = duration;
1814 vp->serial = serial;
1816 /* now we can update the picture count */
1817 frame_queue_push(&is->pictq);
1822 static int get_video_frame(VideoState *is, AVFrame *frame)
1826 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1832 if (frame->pts != AV_NOPTS_VALUE)
1833 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1835 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1837 is->viddec_width = frame->width;
1838 is->viddec_height = frame->height;
1840 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1841 if (frame->pts != AV_NOPTS_VALUE) {
1842 double diff = dpts - get_master_clock(is);
1843 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1844 diff - is->frame_last_filter_delay < 0 &&
1845 is->viddec.pkt_serial == is->vidclk.serial &&
1846 is->videoq.nb_packets) {
1847 is->frame_drops_early++;
1848 av_frame_unref(frame);
1859 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1860 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1863 int nb_filters = graph->nb_filters;
1864 AVFilterInOut *outputs = NULL, *inputs = NULL;
1867 outputs = avfilter_inout_alloc();
1868 inputs = avfilter_inout_alloc();
1869 if (!outputs || !inputs) {
1870 ret = AVERROR(ENOMEM);
1874 outputs->name = av_strdup("in");
1875 outputs->filter_ctx = source_ctx;
1876 outputs->pad_idx = 0;
1877 outputs->next = NULL;
1879 inputs->name = av_strdup("out");
1880 inputs->filter_ctx = sink_ctx;
1881 inputs->pad_idx = 0;
1882 inputs->next = NULL;
1884 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1887 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1891 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1892 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1893 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1895 ret = avfilter_graph_config(graph, NULL);
1897 avfilter_inout_free(&outputs);
1898 avfilter_inout_free(&inputs);
1902 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1904 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1905 char sws_flags_str[512] = "";
1906 char buffersrc_args[256];
1908 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1909 AVCodecContext *codec = is->video_st->codec;
1910 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1911 AVDictionaryEntry *e = NULL;
1913 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1914 if (!strcmp(e->key, "sws_flags")) {
1915 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1917 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1919 if (strlen(sws_flags_str))
1920 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1922 graph->scale_sws_opts = av_strdup(sws_flags_str);
1924 snprintf(buffersrc_args, sizeof(buffersrc_args),
1925 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1926 frame->width, frame->height, frame->format,
1927 is->video_st->time_base.num, is->video_st->time_base.den,
1928 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1929 if (fr.num && fr.den)
1930 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1932 if ((ret = avfilter_graph_create_filter(&filt_src,
1933 avfilter_get_by_name("buffer"),
1934 "ffplay_buffer", buffersrc_args, NULL,
1938 ret = avfilter_graph_create_filter(&filt_out,
1939 avfilter_get_by_name("buffersink"),
1940 "ffplay_buffersink", NULL, NULL, graph);
1944 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1947 last_filter = filt_out;
1949 /* Note: this macro adds a filter before the lastly added filter, so the
1950 * processing order of the filters is in reverse */
1951 #define INSERT_FILT(name, arg) do { \
1952 AVFilterContext *filt_ctx; \
1954 ret = avfilter_graph_create_filter(&filt_ctx, \
1955 avfilter_get_by_name(name), \
1956 "ffplay_" name, arg, NULL, graph); \
1960 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1964 last_filter = filt_ctx; \
1967 /* SDL YUV code is not handling odd width/height for some driver
1968 * combinations, therefore we crop the picture to an even width/height. */
1969 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1972 double theta = get_rotation(is->video_st);
1974 if (fabs(theta - 90) < 1.0) {
1975 INSERT_FILT("transpose", "clock");
1976 } else if (fabs(theta - 180) < 1.0) {
1977 INSERT_FILT("hflip", NULL);
1978 INSERT_FILT("vflip", NULL);
1979 } else if (fabs(theta - 270) < 1.0) {
1980 INSERT_FILT("transpose", "cclock");
1981 } else if (fabs(theta) > 1.0) {
1982 char rotate_buf[64];
1983 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1984 INSERT_FILT("rotate", rotate_buf);
1988 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1991 is->in_video_filter = filt_src;
1992 is->out_video_filter = filt_out;
1998 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
2000 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2001 int sample_rates[2] = { 0, -1 };
2002 int64_t channel_layouts[2] = { 0, -1 };
2003 int channels[2] = { 0, -1 };
2004 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2005 char aresample_swr_opts[512] = "";
2006 AVDictionaryEntry *e = NULL;
2007 char asrc_args[256];
2010 avfilter_graph_free(&is->agraph);
2011 if (!(is->agraph = avfilter_graph_alloc()))
2012 return AVERROR(ENOMEM);
2014 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2015 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2016 if (strlen(aresample_swr_opts))
2017 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2018 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2020 ret = snprintf(asrc_args, sizeof(asrc_args),
2021 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2022 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2023 is->audio_filter_src.channels,
2024 1, is->audio_filter_src.freq);
2025 if (is->audio_filter_src.channel_layout)
2026 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2027 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2029 ret = avfilter_graph_create_filter(&filt_asrc,
2030 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2031 asrc_args, NULL, is->agraph);
2036 ret = avfilter_graph_create_filter(&filt_asink,
2037 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2038 NULL, NULL, is->agraph);
2042 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2044 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2047 if (force_output_format) {
2048 channel_layouts[0] = is->audio_tgt.channel_layout;
2049 channels [0] = is->audio_tgt.channels;
2050 sample_rates [0] = is->audio_tgt.freq;
2051 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2053 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2055 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2057 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2062 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2065 is->in_audio_filter = filt_asrc;
2066 is->out_audio_filter = filt_asink;
2070 avfilter_graph_free(&is->agraph);
2073 #endif /* CONFIG_AVFILTER */
2075 static int audio_thread(void *arg)
2077 VideoState *is = arg;
2078 AVFrame *frame = av_frame_alloc();
2081 int last_serial = -1;
2082 int64_t dec_channel_layout;
2090 return AVERROR(ENOMEM);
2093 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2097 tb = (AVRational){1, frame->sample_rate};
2100 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2103 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2104 frame->format, av_frame_get_channels(frame)) ||
2105 is->audio_filter_src.channel_layout != dec_channel_layout ||
2106 is->audio_filter_src.freq != frame->sample_rate ||
2107 is->auddec.pkt_serial != last_serial;
2110 char buf1[1024], buf2[1024];
2111 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2112 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2113 av_log(NULL, AV_LOG_DEBUG,
2114 "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",
2115 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2116 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2118 is->audio_filter_src.fmt = frame->format;
2119 is->audio_filter_src.channels = av_frame_get_channels(frame);
2120 is->audio_filter_src.channel_layout = dec_channel_layout;
2121 is->audio_filter_src.freq = frame->sample_rate;
2122 last_serial = is->auddec.pkt_serial;
2124 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2128 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2131 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2132 tb = is->out_audio_filter->inputs[0]->time_base;
2134 if (!(af = frame_queue_peek_writable(&is->sampq)))
2137 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2138 af->pos = av_frame_get_pkt_pos(frame);
2139 af->serial = is->auddec.pkt_serial;
2140 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2142 av_frame_move_ref(af->frame, frame);
2143 frame_queue_push(&is->sampq);
2146 if (is->audioq.serial != is->auddec.pkt_serial)
2149 if (ret == AVERROR_EOF)
2150 is->auddec.finished = is->auddec.pkt_serial;
2153 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2156 avfilter_graph_free(&is->agraph);
2158 av_frame_free(&frame);
2162 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2164 packet_queue_start(d->queue);
2165 d->decoder_tid = SDL_CreateThread(fn, arg);
2166 if (!d->decoder_tid) {
2167 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2168 return AVERROR(ENOMEM);
2173 static int video_thread(void *arg)
2175 VideoState *is = arg;
2176 AVFrame *frame = av_frame_alloc();
2180 AVRational tb = is->video_st->time_base;
2181 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2184 AVFilterGraph *graph = avfilter_graph_alloc();
2185 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2188 enum AVPixelFormat last_format = -2;
2189 int last_serial = -1;
2190 int last_vfilter_idx = 0;
2192 av_frame_free(&frame);
2193 return AVERROR(ENOMEM);
2200 avfilter_graph_free(&graph);
2202 return AVERROR(ENOMEM);
2206 ret = get_video_frame(is, frame);
2213 if ( last_w != frame->width
2214 || last_h != frame->height
2215 || last_format != frame->format
2216 || last_serial != is->viddec.pkt_serial
2217 || last_vfilter_idx != is->vfilter_idx) {
2218 av_log(NULL, AV_LOG_DEBUG,
2219 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2221 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2222 frame->width, frame->height,
2223 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2224 avfilter_graph_free(&graph);
2225 graph = avfilter_graph_alloc();
2226 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2228 event.type = FF_QUIT_EVENT;
2229 event.user.data1 = is;
2230 SDL_PushEvent(&event);
2233 filt_in = is->in_video_filter;
2234 filt_out = is->out_video_filter;
2235 last_w = frame->width;
2236 last_h = frame->height;
2237 last_format = frame->format;
2238 last_serial = is->viddec.pkt_serial;
2239 last_vfilter_idx = is->vfilter_idx;
2240 frame_rate = filt_out->inputs[0]->frame_rate;
2243 ret = av_buffersrc_add_frame(filt_in, frame);
2248 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2250 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2252 if (ret == AVERROR_EOF)
2253 is->viddec.finished = is->viddec.pkt_serial;
2258 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2259 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2260 is->frame_last_filter_delay = 0;
2261 tb = filt_out->inputs[0]->time_base;
2263 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2264 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2265 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2266 av_frame_unref(frame);
2276 avfilter_graph_free(&graph);
2278 av_frame_free(&frame);
2282 static int subtitle_thread(void *arg)
2284 VideoState *is = arg;
2291 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2294 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2299 if (got_subtitle && sp->sub.format == 0) {
2300 if (sp->sub.pts != AV_NOPTS_VALUE)
2301 pts = sp->sub.pts / (double)AV_TIME_BASE;
2303 sp->serial = is->subdec.pkt_serial;
2304 if (!(sp->subrects = av_mallocz_array(sp->sub.num_rects, sizeof(AVSubtitleRect*)))) {
2305 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subrects\n");
2309 for (i = 0; i < sp->sub.num_rects; i++)
2311 int in_w = sp->sub.rects[i]->w;
2312 int in_h = sp->sub.rects[i]->h;
2313 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2314 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2315 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2316 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2318 if (!(sp->subrects[i] = av_mallocz(sizeof(AVSubtitleRect))) ||
2319 av_image_alloc(sp->subrects[i]->data, sp->subrects[i]->linesize, out_w, out_h, AV_PIX_FMT_YUVA420P, 16) < 0) {
2320 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subtitle data\n");
2324 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2325 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2326 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2327 if (!is->sub_convert_ctx) {
2328 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2331 sws_scale(is->sub_convert_ctx,
2332 (void*)sp->sub.rects[i]->data, sp->sub.rects[i]->linesize,
2333 0, in_h, sp->subrects[i]->data, sp->subrects[i]->linesize);
2335 sp->subrects[i]->w = out_w;
2336 sp->subrects[i]->h = out_h;
2337 sp->subrects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2338 sp->subrects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2341 /* now we can update the picture count */
2342 frame_queue_push(&is->subpq);
2343 } else if (got_subtitle) {
2344 avsubtitle_free(&sp->sub);
2350 /* copy samples for viewing in editor window */
2351 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2355 size = samples_size / sizeof(short);
2357 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2360 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2362 is->sample_array_index += len;
2363 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2364 is->sample_array_index = 0;
2369 /* return the wanted number of samples to get better sync if sync_type is video
2370 * or external master clock */
2371 static int synchronize_audio(VideoState *is, int nb_samples)
2373 int wanted_nb_samples = nb_samples;
2375 /* if not master, then we try to remove or add samples to correct the clock */
2376 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2377 double diff, avg_diff;
2378 int min_nb_samples, max_nb_samples;
2380 diff = get_clock(&is->audclk) - get_master_clock(is);
2382 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2383 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2384 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2385 /* not enough measures to have a correct estimate */
2386 is->audio_diff_avg_count++;
2388 /* estimate the A-V difference */
2389 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2391 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2392 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2393 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2394 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2395 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2397 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2398 diff, avg_diff, wanted_nb_samples - nb_samples,
2399 is->audio_clock, is->audio_diff_threshold);
2402 /* too big difference : may be initial PTS errors, so
2404 is->audio_diff_avg_count = 0;
2405 is->audio_diff_cum = 0;
2409 return wanted_nb_samples;
2413 * Decode one audio frame and return its uncompressed size.
2415 * The processed audio frame is decoded, converted if required, and
2416 * stored in is->audio_buf, with size in bytes given by the return
2419 static int audio_decode_frame(VideoState *is)
2421 int data_size, resampled_data_size;
2422 int64_t dec_channel_layout;
2423 av_unused double audio_clock0;
2424 int wanted_nb_samples;
2432 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2433 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2438 if (!(af = frame_queue_peek_readable(&is->sampq)))
2440 frame_queue_next(&is->sampq);
2441 } while (af->serial != is->audioq.serial);
2443 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2444 af->frame->nb_samples,
2445 af->frame->format, 1);
2447 dec_channel_layout =
2448 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2449 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2450 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2452 if (af->frame->format != is->audio_src.fmt ||
2453 dec_channel_layout != is->audio_src.channel_layout ||
2454 af->frame->sample_rate != is->audio_src.freq ||
2455 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2456 swr_free(&is->swr_ctx);
2457 is->swr_ctx = swr_alloc_set_opts(NULL,
2458 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2459 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2461 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2462 av_log(NULL, AV_LOG_ERROR,
2463 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2464 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2465 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2466 swr_free(&is->swr_ctx);
2469 is->audio_src.channel_layout = dec_channel_layout;
2470 is->audio_src.channels = av_frame_get_channels(af->frame);
2471 is->audio_src.freq = af->frame->sample_rate;
2472 is->audio_src.fmt = af->frame->format;
2476 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2477 uint8_t **out = &is->audio_buf1;
2478 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2479 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2482 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2485 if (wanted_nb_samples != af->frame->nb_samples) {
2486 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2487 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2488 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2492 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2493 if (!is->audio_buf1)
2494 return AVERROR(ENOMEM);
2495 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2497 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2500 if (len2 == out_count) {
2501 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2502 if (swr_init(is->swr_ctx) < 0)
2503 swr_free(&is->swr_ctx);
2505 is->audio_buf = is->audio_buf1;
2506 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2508 is->audio_buf = af->frame->data[0];
2509 resampled_data_size = data_size;
2512 audio_clock0 = is->audio_clock;
2513 /* update the audio clock with the pts */
2514 if (!isnan(af->pts))
2515 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2517 is->audio_clock = NAN;
2518 is->audio_clock_serial = af->serial;
2521 static double last_clock;
2522 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2523 is->audio_clock - last_clock,
2524 is->audio_clock, audio_clock0);
2525 last_clock = is->audio_clock;
2528 return resampled_data_size;
2531 /* prepare a new audio buffer */
2532 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2534 VideoState *is = opaque;
2535 int audio_size, len1;
2537 audio_callback_time = av_gettime_relative();
2540 if (is->audio_buf_index >= is->audio_buf_size) {
2541 audio_size = audio_decode_frame(is);
2542 if (audio_size < 0) {
2543 /* if error, just output silence */
2544 is->audio_buf = is->silence_buf;
2545 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2547 if (is->show_mode != SHOW_MODE_VIDEO)
2548 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2549 is->audio_buf_size = audio_size;
2551 is->audio_buf_index = 0;
2553 len1 = is->audio_buf_size - is->audio_buf_index;
2556 if (!is->muted && is->audio_volume == SDL_MIX_MAXVOLUME)
2557 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2559 memset(stream, is->silence_buf[0], len1);
2561 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2565 is->audio_buf_index += len1;
2567 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2568 /* Let's assume the audio driver that is used by SDL has two periods. */
2569 if (!isnan(is->audio_clock)) {
2570 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);
2571 sync_clock_to_slave(&is->extclk, &is->audclk);
2575 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2577 SDL_AudioSpec wanted_spec, spec;
2579 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2580 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2581 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2583 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2585 wanted_nb_channels = atoi(env);
2586 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2588 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2589 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2590 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2592 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2593 wanted_spec.channels = wanted_nb_channels;
2594 wanted_spec.freq = wanted_sample_rate;
2595 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2596 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2599 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2600 next_sample_rate_idx--;
2601 wanted_spec.format = AUDIO_S16SYS;
2602 wanted_spec.silence = 0;
2603 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2604 wanted_spec.callback = sdl_audio_callback;
2605 wanted_spec.userdata = opaque;
2606 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2607 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2608 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2609 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2610 if (!wanted_spec.channels) {
2611 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2612 wanted_spec.channels = wanted_nb_channels;
2613 if (!wanted_spec.freq) {
2614 av_log(NULL, AV_LOG_ERROR,
2615 "No more combinations to try, audio open failed\n");
2619 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2621 if (spec.format != AUDIO_S16SYS) {
2622 av_log(NULL, AV_LOG_ERROR,
2623 "SDL advised audio format %d is not supported!\n", spec.format);
2626 if (spec.channels != wanted_spec.channels) {
2627 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2628 if (!wanted_channel_layout) {
2629 av_log(NULL, AV_LOG_ERROR,
2630 "SDL advised channel count %d is not supported!\n", spec.channels);
2635 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2636 audio_hw_params->freq = spec.freq;
2637 audio_hw_params->channel_layout = wanted_channel_layout;
2638 audio_hw_params->channels = spec.channels;
2639 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2640 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);
2641 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2642 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2648 /* open a given stream. Return 0 if OK */
2649 static int stream_component_open(VideoState *is, int stream_index)
2651 AVFormatContext *ic = is->ic;
2652 AVCodecContext *avctx;
2654 const char *forced_codec_name = NULL;
2656 AVDictionaryEntry *t = NULL;
2657 int sample_rate, nb_channels;
2658 int64_t channel_layout;
2660 int stream_lowres = lowres;
2662 if (stream_index < 0 || stream_index >= ic->nb_streams)
2664 avctx = ic->streams[stream_index]->codec;
2666 codec = avcodec_find_decoder(avctx->codec_id);
2668 switch(avctx->codec_type){
2669 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2670 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2671 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2673 if (forced_codec_name)
2674 codec = avcodec_find_decoder_by_name(forced_codec_name);
2676 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2677 "No codec could be found with name '%s'\n", forced_codec_name);
2678 else av_log(NULL, AV_LOG_WARNING,
2679 "No codec could be found with id %d\n", avctx->codec_id);
2683 avctx->codec_id = codec->id;
2684 if(stream_lowres > av_codec_get_max_lowres(codec)){
2685 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2686 av_codec_get_max_lowres(codec));
2687 stream_lowres = av_codec_get_max_lowres(codec);
2689 av_codec_set_lowres(avctx, stream_lowres);
2692 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2695 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2697 if(codec->capabilities & AV_CODEC_CAP_DR1)
2698 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2701 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2702 if (!av_dict_get(opts, "threads", NULL, 0))
2703 av_dict_set(&opts, "threads", "auto", 0);
2705 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2706 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2707 av_dict_set(&opts, "refcounted_frames", "1", 0);
2708 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2711 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2712 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2713 ret = AVERROR_OPTION_NOT_FOUND;
2718 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2719 switch (avctx->codec_type) {
2720 case AVMEDIA_TYPE_AUDIO:
2725 is->audio_filter_src.freq = avctx->sample_rate;
2726 is->audio_filter_src.channels = avctx->channels;
2727 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2728 is->audio_filter_src.fmt = avctx->sample_fmt;
2729 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2731 link = is->out_audio_filter->inputs[0];
2732 sample_rate = link->sample_rate;
2733 nb_channels = link->channels;
2734 channel_layout = link->channel_layout;
2737 sample_rate = avctx->sample_rate;
2738 nb_channels = avctx->channels;
2739 channel_layout = avctx->channel_layout;
2742 /* prepare audio output */
2743 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2745 is->audio_hw_buf_size = ret;
2746 is->audio_src = is->audio_tgt;
2747 is->audio_buf_size = 0;
2748 is->audio_buf_index = 0;
2750 /* init averaging filter */
2751 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2752 is->audio_diff_avg_count = 0;
2753 /* since we do not have a precise anough audio fifo fullness,
2754 we correct audio sync only if larger than this threshold */
2755 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2757 is->audio_stream = stream_index;
2758 is->audio_st = ic->streams[stream_index];
2760 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2761 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2762 is->auddec.start_pts = is->audio_st->start_time;
2763 is->auddec.start_pts_tb = is->audio_st->time_base;
2765 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2769 case AVMEDIA_TYPE_VIDEO:
2770 is->video_stream = stream_index;
2771 is->video_st = ic->streams[stream_index];
2773 is->viddec_width = avctx->width;
2774 is->viddec_height = avctx->height;
2776 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2777 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2779 is->queue_attachments_req = 1;
2781 case AVMEDIA_TYPE_SUBTITLE:
2782 is->subtitle_stream = stream_index;
2783 is->subtitle_st = ic->streams[stream_index];
2785 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2786 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2794 av_dict_free(&opts);
2799 static int decode_interrupt_cb(void *ctx)
2801 VideoState *is = ctx;
2802 return is->abort_request;
2805 static int is_realtime(AVFormatContext *s)
2807 if( !strcmp(s->iformat->name, "rtp")
2808 || !strcmp(s->iformat->name, "rtsp")
2809 || !strcmp(s->iformat->name, "sdp")
2813 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2814 || !strncmp(s->filename, "udp:", 4)
2821 /* this thread gets the stream from the disk or the network */
2822 static int read_thread(void *arg)
2824 VideoState *is = arg;
2825 AVFormatContext *ic = NULL;
2827 int st_index[AVMEDIA_TYPE_NB];
2828 AVPacket pkt1, *pkt = &pkt1;
2829 int64_t stream_start_time;
2830 int pkt_in_play_range = 0;
2831 AVDictionaryEntry *t;
2832 AVDictionary **opts;
2833 int orig_nb_streams;
2834 SDL_mutex *wait_mutex = SDL_CreateMutex();
2835 int scan_all_pmts_set = 0;
2839 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2840 ret = AVERROR(ENOMEM);
2844 memset(st_index, -1, sizeof(st_index));
2845 is->last_video_stream = is->video_stream = -1;
2846 is->last_audio_stream = is->audio_stream = -1;
2847 is->last_subtitle_stream = is->subtitle_stream = -1;
2850 ic = avformat_alloc_context();
2852 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2853 ret = AVERROR(ENOMEM);
2856 ic->interrupt_callback.callback = decode_interrupt_cb;
2857 ic->interrupt_callback.opaque = is;
2858 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2859 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2860 scan_all_pmts_set = 1;
2862 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2864 print_error(is->filename, err);
2868 if (scan_all_pmts_set)
2869 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2871 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2872 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2873 ret = AVERROR_OPTION_NOT_FOUND;
2879 ic->flags |= AVFMT_FLAG_GENPTS;
2881 av_format_inject_global_side_data(ic);
2883 opts = setup_find_stream_info_opts(ic, codec_opts);
2884 orig_nb_streams = ic->nb_streams;
2886 err = avformat_find_stream_info(ic, opts);
2888 for (i = 0; i < orig_nb_streams; i++)
2889 av_dict_free(&opts[i]);
2893 av_log(NULL, AV_LOG_WARNING,
2894 "%s: could not find codec parameters\n", is->filename);
2900 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2902 if (seek_by_bytes < 0)
2903 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2905 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2907 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2908 window_title = av_asprintf("%s - %s", t->value, input_filename);
2910 /* if seeking requested, we execute it */
2911 if (start_time != AV_NOPTS_VALUE) {
2914 timestamp = start_time;
2915 /* add the stream start time */
2916 if (ic->start_time != AV_NOPTS_VALUE)
2917 timestamp += ic->start_time;
2918 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2920 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2921 is->filename, (double)timestamp / AV_TIME_BASE);
2925 is->realtime = is_realtime(ic);
2928 av_dump_format(ic, 0, is->filename, 0);
2930 for (i = 0; i < ic->nb_streams; i++) {
2931 AVStream *st = ic->streams[i];
2932 enum AVMediaType type = st->codec->codec_type;
2933 st->discard = AVDISCARD_ALL;
2934 if (wanted_stream_spec[type] && st_index[type] == -1)
2935 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2938 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2939 if (wanted_stream_spec[i] && st_index[i] == -1) {
2940 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));
2941 st_index[i] = INT_MAX;
2946 st_index[AVMEDIA_TYPE_VIDEO] =
2947 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2948 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2950 st_index[AVMEDIA_TYPE_AUDIO] =
2951 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2952 st_index[AVMEDIA_TYPE_AUDIO],
2953 st_index[AVMEDIA_TYPE_VIDEO],
2955 if (!video_disable && !subtitle_disable)
2956 st_index[AVMEDIA_TYPE_SUBTITLE] =
2957 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2958 st_index[AVMEDIA_TYPE_SUBTITLE],
2959 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2960 st_index[AVMEDIA_TYPE_AUDIO] :
2961 st_index[AVMEDIA_TYPE_VIDEO]),
2964 is->show_mode = show_mode;
2965 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2966 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2967 AVCodecContext *avctx = st->codec;
2968 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2970 set_default_window_size(avctx->width, avctx->height, sar);
2973 /* open the streams */
2974 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2975 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2979 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2980 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2982 if (is->show_mode == SHOW_MODE_NONE)
2983 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2985 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2986 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2989 if (is->video_stream < 0 && is->audio_stream < 0) {
2990 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2996 if (infinite_buffer < 0 && is->realtime)
2997 infinite_buffer = 1;
3000 if (is->abort_request)
3002 if (is->paused != is->last_paused) {
3003 is->last_paused = is->paused;
3005 is->read_pause_return = av_read_pause(ic);
3009 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3011 (!strcmp(ic->iformat->name, "rtsp") ||
3012 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3013 /* wait 10 ms to avoid trying to get another packet */
3020 int64_t seek_target = is->seek_pos;
3021 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3022 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3023 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3024 // of the seek_pos/seek_rel variables
3026 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3028 av_log(NULL, AV_LOG_ERROR,
3029 "%s: error while seeking\n", is->ic->filename);
3031 if (is->audio_stream >= 0) {
3032 packet_queue_flush(&is->audioq);
3033 packet_queue_put(&is->audioq, &flush_pkt);
3035 if (is->subtitle_stream >= 0) {
3036 packet_queue_flush(&is->subtitleq);
3037 packet_queue_put(&is->subtitleq, &flush_pkt);
3039 if (is->video_stream >= 0) {
3040 packet_queue_flush(&is->videoq);
3041 packet_queue_put(&is->videoq, &flush_pkt);
3043 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3044 set_clock(&is->extclk, NAN, 0);
3046 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3050 is->queue_attachments_req = 1;
3053 step_to_next_frame(is);
3055 if (is->queue_attachments_req) {
3056 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3058 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3060 packet_queue_put(&is->videoq, ©);
3061 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3063 is->queue_attachments_req = 0;
3066 /* if the queue are full, no need to read more */
3067 if (infinite_buffer<1 &&
3068 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3069 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3070 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3071 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3072 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3074 SDL_LockMutex(wait_mutex);
3075 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3076 SDL_UnlockMutex(wait_mutex);
3080 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3081 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3082 if (loop != 1 && (!loop || --loop)) {
3083 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3084 } else if (autoexit) {
3089 ret = av_read_frame(ic, pkt);
3091 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3092 if (is->video_stream >= 0)
3093 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3094 if (is->audio_stream >= 0)
3095 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3096 if (is->subtitle_stream >= 0)
3097 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3100 if (ic->pb && ic->pb->error)
3102 SDL_LockMutex(wait_mutex);
3103 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3104 SDL_UnlockMutex(wait_mutex);
3109 /* check if packet is in play range specified by user, then queue, otherwise discard */
3110 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3111 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3112 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3113 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3114 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3115 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3116 <= ((double)duration / 1000000);
3117 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3118 packet_queue_put(&is->audioq, pkt);
3119 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3120 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3121 packet_queue_put(&is->videoq, pkt);
3122 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3123 packet_queue_put(&is->subtitleq, pkt);
3125 av_packet_unref(pkt);
3132 avformat_close_input(&ic);
3137 event.type = FF_QUIT_EVENT;
3138 event.user.data1 = is;
3139 SDL_PushEvent(&event);
3141 SDL_DestroyMutex(wait_mutex);
3145 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3149 is = av_mallocz(sizeof(VideoState));
3152 is->filename = av_strdup(filename);
3155 is->iformat = iformat;
3159 /* start video display */
3160 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3162 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3164 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3167 if (packet_queue_init(&is->videoq) < 0 ||
3168 packet_queue_init(&is->audioq) < 0 ||
3169 packet_queue_init(&is->subtitleq) < 0)
3172 if (!(is->continue_read_thread = SDL_CreateCond())) {
3173 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3177 init_clock(&is->vidclk, &is->videoq.serial);
3178 init_clock(&is->audclk, &is->audioq.serial);
3179 init_clock(&is->extclk, &is->extclk.serial);
3180 is->audio_clock_serial = -1;
3181 is->audio_volume = SDL_MIX_MAXVOLUME;
3183 is->av_sync_type = av_sync_type;
3184 is->read_tid = SDL_CreateThread(read_thread, is);
3185 if (!is->read_tid) {
3186 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3194 static void stream_cycle_channel(VideoState *is, int codec_type)
3196 AVFormatContext *ic = is->ic;
3197 int start_index, stream_index;
3200 AVProgram *p = NULL;
3201 int nb_streams = is->ic->nb_streams;
3203 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3204 start_index = is->last_video_stream;
3205 old_index = is->video_stream;
3206 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3207 start_index = is->last_audio_stream;
3208 old_index = is->audio_stream;
3210 start_index = is->last_subtitle_stream;
3211 old_index = is->subtitle_stream;
3213 stream_index = start_index;
3215 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3216 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3218 nb_streams = p->nb_stream_indexes;
3219 for (start_index = 0; start_index < nb_streams; start_index++)
3220 if (p->stream_index[start_index] == stream_index)
3222 if (start_index == nb_streams)
3224 stream_index = start_index;
3229 if (++stream_index >= nb_streams)
3231 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3234 is->last_subtitle_stream = -1;
3237 if (start_index == -1)
3241 if (stream_index == start_index)
3243 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3244 if (st->codec->codec_type == codec_type) {
3245 /* check that parameters are OK */
3246 switch (codec_type) {
3247 case AVMEDIA_TYPE_AUDIO:
3248 if (st->codec->sample_rate != 0 &&
3249 st->codec->channels != 0)
3252 case AVMEDIA_TYPE_VIDEO:
3253 case AVMEDIA_TYPE_SUBTITLE:
3261 if (p && stream_index != -1)
3262 stream_index = p->stream_index[stream_index];
3263 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3264 av_get_media_type_string(codec_type),
3268 stream_component_close(is, old_index);
3269 stream_component_open(is, stream_index);
3273 static void toggle_full_screen(VideoState *is)
3275 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3276 /* OS X needs to reallocate the SDL overlays */
3278 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3279 is->pictq.queue[i].reallocate = 1;
3281 is_full_screen = !is_full_screen;
3282 video_open(is, 1, NULL);
3285 static void toggle_audio_display(VideoState *is)
3287 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3288 int next = is->show_mode;
3290 next = (next + 1) % SHOW_MODE_NB;
3291 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3292 if (is->show_mode != next) {
3293 fill_rectangle(screen,
3294 is->xleft, is->ytop, is->width, is->height,
3296 is->force_refresh = 1;
3297 is->show_mode = next;
3301 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3302 double remaining_time = 0.0;
3304 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3305 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3309 if (remaining_time > 0.0)
3310 av_usleep((int64_t)(remaining_time * 1000000.0));
3311 remaining_time = REFRESH_RATE;
3312 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3313 video_refresh(is, &remaining_time);
3318 static void seek_chapter(VideoState *is, int incr)
3320 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3323 if (!is->ic->nb_chapters)
3326 /* find the current chapter */
3327 for (i = 0; i < is->ic->nb_chapters; i++) {
3328 AVChapter *ch = is->ic->chapters[i];
3329 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3337 if (i >= is->ic->nb_chapters)
3340 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3341 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3342 AV_TIME_BASE_Q), 0, 0);
3345 /* handle an event sent by the GUI */
3346 static void event_loop(VideoState *cur_stream)
3349 double incr, pos, frac;
3353 refresh_loop_wait_event(cur_stream, &event);
3354 switch (event.type) {
3356 if (exit_on_keydown) {
3357 do_exit(cur_stream);
3360 switch (event.key.keysym.sym) {
3363 do_exit(cur_stream);
3366 toggle_full_screen(cur_stream);
3367 cur_stream->force_refresh = 1;
3371 toggle_pause(cur_stream);
3374 toggle_mute(cur_stream);
3376 case SDLK_KP_MULTIPLY:
3378 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3380 case SDLK_KP_DIVIDE:
3382 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3384 case SDLK_s: // S: Step to next frame
3385 step_to_next_frame(cur_stream);
3388 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3391 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3394 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3395 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3396 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3399 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3403 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3404 if (++cur_stream->vfilter_idx >= nb_vfilters)
3405 cur_stream->vfilter_idx = 0;
3407 cur_stream->vfilter_idx = 0;
3408 toggle_audio_display(cur_stream);
3411 toggle_audio_display(cur_stream);
3415 if (cur_stream->ic->nb_chapters <= 1) {
3419 seek_chapter(cur_stream, 1);
3422 if (cur_stream->ic->nb_chapters <= 1) {
3426 seek_chapter(cur_stream, -1);
3440 if (seek_by_bytes) {
3442 if (pos < 0 && cur_stream->video_stream >= 0)
3443 pos = frame_queue_last_pos(&cur_stream->pictq);
3444 if (pos < 0 && cur_stream->audio_stream >= 0)
3445 pos = frame_queue_last_pos(&cur_stream->sampq);
3447 pos = avio_tell(cur_stream->ic->pb);
3448 if (cur_stream->ic->bit_rate)
3449 incr *= cur_stream->ic->bit_rate / 8.0;
3453 stream_seek(cur_stream, pos, incr, 1);
3455 pos = get_master_clock(cur_stream);
3457 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3459 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3460 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3461 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3468 case SDL_VIDEOEXPOSE:
3469 cur_stream->force_refresh = 1;
3471 case SDL_MOUSEBUTTONDOWN:
3472 if (exit_on_mousedown) {
3473 do_exit(cur_stream);
3476 if (event.button.button == SDL_BUTTON_LEFT) {
3477 static int64_t last_mouse_left_click = 0;
3478 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3479 toggle_full_screen(cur_stream);
3480 cur_stream->force_refresh = 1;
3481 last_mouse_left_click = 0;
3483 last_mouse_left_click = av_gettime_relative();
3486 case SDL_MOUSEMOTION:
3487 if (cursor_hidden) {
3491 cursor_last_shown = av_gettime_relative();
3492 if (event.type == SDL_MOUSEBUTTONDOWN) {
3493 if (event.button.button != SDL_BUTTON_RIGHT)
3497 if (!(event.motion.state & SDL_BUTTON_RMASK))
3501 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3502 uint64_t size = avio_size(cur_stream->ic->pb);
3503 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3507 int tns, thh, tmm, tss;
3508 tns = cur_stream->ic->duration / 1000000LL;
3510 tmm = (tns % 3600) / 60;
3512 frac = x / cur_stream->width;
3515 mm = (ns % 3600) / 60;
3517 av_log(NULL, AV_LOG_INFO,
3518 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3519 hh, mm, ss, thh, tmm, tss);
3520 ts = frac * cur_stream->ic->duration;
3521 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3522 ts += cur_stream->ic->start_time;
3523 stream_seek(cur_stream, ts, 0, 0);
3526 case SDL_VIDEORESIZE:
3527 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3528 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3530 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3531 do_exit(cur_stream);
3533 screen_width = cur_stream->width = screen->w;
3534 screen_height = cur_stream->height = screen->h;
3535 cur_stream->force_refresh = 1;
3539 do_exit(cur_stream);
3541 case FF_ALLOC_EVENT:
3542 alloc_picture(event.user.data1);
3550 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3552 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3553 return opt_default(NULL, "video_size", arg);
3556 static int opt_width(void *optctx, const char *opt, const char *arg)
3558 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3562 static int opt_height(void *optctx, const char *opt, const char *arg)
3564 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3568 static int opt_format(void *optctx, const char *opt, const char *arg)
3570 file_iformat = av_find_input_format(arg);
3571 if (!file_iformat) {
3572 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3573 return AVERROR(EINVAL);
3578 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3580 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3581 return opt_default(NULL, "pixel_format", arg);
3584 static int opt_sync(void *optctx, const char *opt, const char *arg)
3586 if (!strcmp(arg, "audio"))
3587 av_sync_type = AV_SYNC_AUDIO_MASTER;
3588 else if (!strcmp(arg, "video"))
3589 av_sync_type = AV_SYNC_VIDEO_MASTER;
3590 else if (!strcmp(arg, "ext"))
3591 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3593 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3599 static int opt_seek(void *optctx, const char *opt, const char *arg)
3601 start_time = parse_time_or_die(opt, arg, 1);
3605 static int opt_duration(void *optctx, const char *opt, const char *arg)
3607 duration = parse_time_or_die(opt, arg, 1);
3611 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3613 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3614 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3615 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3616 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3620 static void opt_input_file(void *optctx, const char *filename)
3622 if (input_filename) {
3623 av_log(NULL, AV_LOG_FATAL,
3624 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3625 filename, input_filename);
3628 if (!strcmp(filename, "-"))
3630 input_filename = filename;
3633 static int opt_codec(void *optctx, const char *opt, const char *arg)
3635 const char *spec = strchr(opt, ':');
3637 av_log(NULL, AV_LOG_ERROR,
3638 "No media specifier was specified in '%s' in option '%s'\n",
3640 return AVERROR(EINVAL);
3644 case 'a' : audio_codec_name = arg; break;
3645 case 's' : subtitle_codec_name = arg; break;
3646 case 'v' : video_codec_name = arg; break;
3648 av_log(NULL, AV_LOG_ERROR,
3649 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3650 return AVERROR(EINVAL);
3657 static const OptionDef options[] = {
3658 #include "cmdutils_common_opts.h"
3659 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3660 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3661 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3662 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3663 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3664 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3665 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3666 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3667 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3668 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3669 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3670 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3671 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3672 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3673 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3674 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3675 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3676 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3677 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3678 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3679 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3680 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3681 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3682 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3683 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3684 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3685 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3686 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3687 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3689 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3690 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3692 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3693 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3694 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3695 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3696 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3697 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3698 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3699 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3700 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3704 static void show_usage(void)
3706 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3707 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3708 av_log(NULL, AV_LOG_INFO, "\n");
3711 void show_help_default(const char *opt, const char *arg)
3713 av_log_set_callback(log_callback_help);
3715 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3716 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3718 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3719 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3720 #if !CONFIG_AVFILTER
3721 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3723 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3725 printf("\nWhile playing:\n"
3727 "f toggle full screen\n"
3730 "9, 0 decrease and increase volume respectively\n"
3731 "/, * decrease and increase volume respectively\n"
3732 "a cycle audio channel in the current program\n"
3733 "v cycle video channel\n"
3734 "t cycle subtitle channel in the current program\n"
3736 "w cycle video filters or show modes\n"
3737 "s activate frame-step mode\n"
3738 "left/right seek backward/forward 10 seconds\n"
3739 "down/up seek backward/forward 1 minute\n"
3740 "page down/page up seek backward/forward 10 minutes\n"
3741 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3742 "left double-click toggle full screen\n"
3746 static int lockmgr(void **mtx, enum AVLockOp op)
3749 case AV_LOCK_CREATE:
3750 *mtx = SDL_CreateMutex();
3752 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3756 case AV_LOCK_OBTAIN:
3757 return !!SDL_LockMutex(*mtx);
3758 case AV_LOCK_RELEASE:
3759 return !!SDL_UnlockMutex(*mtx);
3760 case AV_LOCK_DESTROY:
3761 SDL_DestroyMutex(*mtx);
3767 /* Called from the main */
3768 int main(int argc, char **argv)
3772 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3774 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3775 parse_loglevel(argc, argv, options);
3777 /* register all codecs, demux and protocols */
3779 avdevice_register_all();
3782 avfilter_register_all();
3785 avformat_network_init();
3789 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3790 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3792 show_banner(argc, argv, options);
3794 parse_options(NULL, argc, argv, options, opt_input_file);
3796 if (!input_filename) {
3798 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3799 av_log(NULL, AV_LOG_FATAL,
3800 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3804 if (display_disable) {
3807 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3809 flags &= ~SDL_INIT_AUDIO;
3810 if (display_disable)
3811 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3812 #if !defined(_WIN32) && !defined(__APPLE__)
3813 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3815 if (SDL_Init (flags)) {
3816 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3817 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3821 if (!display_disable) {
3822 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3823 fs_screen_width = vi->current_w;
3824 fs_screen_height = vi->current_h;
3827 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3828 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3829 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3831 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3833 if (av_lockmgr_register(lockmgr)) {
3834 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3838 av_init_packet(&flush_pkt);
3839 flush_pkt.data = (uint8_t *)&flush_pkt;
3841 is = stream_open(input_filename, file_iformat);
3843 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");