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(AVPicture *dst, 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 = dst->data[0] + dstx + dsty * dst->linesize[0];
873 cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
874 cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->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 += dst->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 += dst->linesize[1] - dstw/2;
900 cr += dst->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 = ((int)rint(height * aspect_ratio)) & ~1;
931 if (width > scr_width) {
933 height = ((int)rint(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)
951 vp = frame_queue_peek(&is->pictq);
953 if (is->subtitle_st) {
954 if (frame_queue_nb_remaining(&is->subpq) > 0) {
955 sp = frame_queue_peek(&is->subpq);
957 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
958 SDL_LockYUVOverlay (vp->bmp);
960 pict.data[0] = vp->bmp->pixels[0];
961 pict.data[1] = vp->bmp->pixels[2];
962 pict.data[2] = vp->bmp->pixels[1];
964 pict.linesize[0] = vp->bmp->pitches[0];
965 pict.linesize[1] = vp->bmp->pitches[2];
966 pict.linesize[2] = vp->bmp->pitches[1];
968 for (i = 0; i < sp->sub.num_rects; i++)
969 blend_subrect(&pict, sp->subrects[i],
970 vp->bmp->w, vp->bmp->h);
972 SDL_UnlockYUVOverlay (vp->bmp);
977 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
979 SDL_DisplayYUVOverlay(vp->bmp, &rect);
981 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) {
982 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
983 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
984 is->last_display_rect = rect;
989 static inline int compute_mod(int a, int b)
991 return a < 0 ? a%b + b : a%b;
994 static void video_audio_display(VideoState *s)
996 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
997 int ch, channels, h, h2, bgcolor, fgcolor;
999 int rdft_bits, nb_freq;
1001 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1003 nb_freq = 1 << (rdft_bits - 1);
1005 /* compute display index : center on currently output samples */
1006 channels = s->audio_tgt.channels;
1007 nb_display_channels = channels;
1009 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1011 delay = s->audio_write_buf_size;
1014 /* to be more precise, we take into account the time spent since
1015 the last buffer computation */
1016 if (audio_callback_time) {
1017 time_diff = av_gettime_relative() - audio_callback_time;
1018 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1021 delay += 2 * data_used;
1022 if (delay < data_used)
1025 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1026 if (s->show_mode == SHOW_MODE_WAVES) {
1028 for (i = 0; i < 1000; i += channels) {
1029 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1030 int a = s->sample_array[idx];
1031 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1032 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1033 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1035 if (h < score && (b ^ c) < 0) {
1042 s->last_i_start = i_start;
1044 i_start = s->last_i_start;
1047 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1048 if (s->show_mode == SHOW_MODE_WAVES) {
1049 fill_rectangle(screen,
1050 s->xleft, s->ytop, s->width, s->height,
1053 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1055 /* total height for one channel */
1056 h = s->height / nb_display_channels;
1057 /* graph height / 2 */
1059 for (ch = 0; ch < nb_display_channels; ch++) {
1061 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1062 for (x = 0; x < s->width; x++) {
1063 y = (s->sample_array[i] * h2) >> 15;
1070 fill_rectangle(screen,
1071 s->xleft + x, ys, 1, y,
1074 if (i >= SAMPLE_ARRAY_SIZE)
1075 i -= SAMPLE_ARRAY_SIZE;
1079 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1081 for (ch = 1; ch < nb_display_channels; ch++) {
1082 y = s->ytop + ch * h;
1083 fill_rectangle(screen,
1084 s->xleft, y, s->width, 1,
1087 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1089 nb_display_channels= FFMIN(nb_display_channels, 2);
1090 if (rdft_bits != s->rdft_bits) {
1091 av_rdft_end(s->rdft);
1092 av_free(s->rdft_data);
1093 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1094 s->rdft_bits = rdft_bits;
1095 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1097 if (!s->rdft || !s->rdft_data){
1098 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1099 s->show_mode = SHOW_MODE_WAVES;
1102 for (ch = 0; ch < nb_display_channels; ch++) {
1103 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1105 for (x = 0; x < 2 * nb_freq; x++) {
1106 double w = (x-nb_freq) * (1.0 / nb_freq);
1107 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1109 if (i >= SAMPLE_ARRAY_SIZE)
1110 i -= SAMPLE_ARRAY_SIZE;
1112 av_rdft_calc(s->rdft, data[ch]);
1114 /* Least efficient way to do this, we should of course
1115 * directly access it but it is more than fast enough. */
1116 for (y = 0; y < s->height; y++) {
1117 double w = 1 / sqrt(nb_freq);
1118 int a = sqrt(w * hypot(data[0][2 * y + 0], data[0][2 * y + 1]));
1119 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1123 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1125 fill_rectangle(screen,
1126 s->xpos, s->height-y, 1, 1,
1130 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1133 if (s->xpos >= s->width)
1138 static void stream_component_close(VideoState *is, int stream_index)
1140 AVFormatContext *ic = is->ic;
1141 AVCodecContext *avctx;
1143 if (stream_index < 0 || stream_index >= ic->nb_streams)
1145 avctx = ic->streams[stream_index]->codec;
1147 switch (avctx->codec_type) {
1148 case AVMEDIA_TYPE_AUDIO:
1149 decoder_abort(&is->auddec, &is->sampq);
1151 decoder_destroy(&is->auddec);
1152 swr_free(&is->swr_ctx);
1153 av_freep(&is->audio_buf1);
1154 is->audio_buf1_size = 0;
1155 is->audio_buf = NULL;
1158 av_rdft_end(is->rdft);
1159 av_freep(&is->rdft_data);
1164 case AVMEDIA_TYPE_VIDEO:
1165 decoder_abort(&is->viddec, &is->pictq);
1166 decoder_destroy(&is->viddec);
1168 case AVMEDIA_TYPE_SUBTITLE:
1169 decoder_abort(&is->subdec, &is->subpq);
1170 decoder_destroy(&is->subdec);
1176 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1177 avcodec_close(avctx);
1178 switch (avctx->codec_type) {
1179 case AVMEDIA_TYPE_AUDIO:
1180 is->audio_st = NULL;
1181 is->audio_stream = -1;
1183 case AVMEDIA_TYPE_VIDEO:
1184 is->video_st = NULL;
1185 is->video_stream = -1;
1187 case AVMEDIA_TYPE_SUBTITLE:
1188 is->subtitle_st = NULL;
1189 is->subtitle_stream = -1;
1196 static void stream_close(VideoState *is)
1198 /* XXX: use a special url_shutdown call to abort parse cleanly */
1199 is->abort_request = 1;
1200 SDL_WaitThread(is->read_tid, NULL);
1202 /* close each stream */
1203 if (is->audio_stream >= 0)
1204 stream_component_close(is, is->audio_stream);
1205 if (is->video_stream >= 0)
1206 stream_component_close(is, is->video_stream);
1207 if (is->subtitle_stream >= 0)
1208 stream_component_close(is, is->subtitle_stream);
1210 avformat_close_input(&is->ic);
1212 packet_queue_destroy(&is->videoq);
1213 packet_queue_destroy(&is->audioq);
1214 packet_queue_destroy(&is->subtitleq);
1216 /* free all pictures */
1217 frame_queue_destory(&is->pictq);
1218 frame_queue_destory(&is->sampq);
1219 frame_queue_destory(&is->subpq);
1220 SDL_DestroyCond(is->continue_read_thread);
1221 #if !CONFIG_AVFILTER
1222 sws_freeContext(is->img_convert_ctx);
1224 sws_freeContext(is->sub_convert_ctx);
1225 av_free(is->filename);
1229 static void do_exit(VideoState *is)
1234 av_lockmgr_register(NULL);
1237 av_freep(&vfilters_list);
1239 avformat_network_deinit();
1243 av_log(NULL, AV_LOG_QUIET, "%s", "");
1247 static void sigterm_handler(int sig)
1252 static void set_default_window_size(int width, int height, AVRational sar)
1255 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1256 default_width = rect.w;
1257 default_height = rect.h;
1260 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1262 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1265 if (is_full_screen) flags |= SDL_FULLSCREEN;
1266 else flags |= SDL_RESIZABLE;
1268 if (vp && vp->width)
1269 set_default_window_size(vp->width, vp->height, vp->sar);
1271 if (is_full_screen && fs_screen_width) {
1272 w = fs_screen_width;
1273 h = fs_screen_height;
1274 } else if (!is_full_screen && screen_width) {
1281 w = FFMIN(16383, w);
1282 if (screen && is->width == screen->w && screen->w == w
1283 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1285 screen = SDL_SetVideoMode(w, h, 0, flags);
1287 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1291 window_title = input_filename;
1292 SDL_WM_SetCaption(window_title, window_title);
1294 is->width = screen->w;
1295 is->height = screen->h;
1300 /* display the current picture, if any */
1301 static void video_display(VideoState *is)
1304 video_open(is, 0, NULL);
1305 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1306 video_audio_display(is);
1307 else if (is->video_st)
1308 video_image_display(is);
1311 static double get_clock(Clock *c)
1313 if (*c->queue_serial != c->serial)
1318 double time = av_gettime_relative() / 1000000.0;
1319 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1323 static void set_clock_at(Clock *c, double pts, int serial, double time)
1326 c->last_updated = time;
1327 c->pts_drift = c->pts - time;
1331 static void set_clock(Clock *c, double pts, int serial)
1333 double time = av_gettime_relative() / 1000000.0;
1334 set_clock_at(c, pts, serial, time);
1337 static void set_clock_speed(Clock *c, double speed)
1339 set_clock(c, get_clock(c), c->serial);
1343 static void init_clock(Clock *c, int *queue_serial)
1347 c->queue_serial = queue_serial;
1348 set_clock(c, NAN, -1);
1351 static void sync_clock_to_slave(Clock *c, Clock *slave)
1353 double clock = get_clock(c);
1354 double slave_clock = get_clock(slave);
1355 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1356 set_clock(c, slave_clock, slave->serial);
1359 static int get_master_sync_type(VideoState *is) {
1360 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1362 return AV_SYNC_VIDEO_MASTER;
1364 return AV_SYNC_AUDIO_MASTER;
1365 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1367 return AV_SYNC_AUDIO_MASTER;
1369 return AV_SYNC_EXTERNAL_CLOCK;
1371 return AV_SYNC_EXTERNAL_CLOCK;
1375 /* get the current master clock value */
1376 static double get_master_clock(VideoState *is)
1380 switch (get_master_sync_type(is)) {
1381 case AV_SYNC_VIDEO_MASTER:
1382 val = get_clock(&is->vidclk);
1384 case AV_SYNC_AUDIO_MASTER:
1385 val = get_clock(&is->audclk);
1388 val = get_clock(&is->extclk);
1394 static void check_external_clock_speed(VideoState *is) {
1395 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1396 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1397 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1398 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1399 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1400 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1402 double speed = is->extclk.speed;
1404 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1408 /* seek in the stream */
1409 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1411 if (!is->seek_req) {
1414 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1416 is->seek_flags |= AVSEEK_FLAG_BYTE;
1418 SDL_CondSignal(is->continue_read_thread);
1422 /* pause or resume the video */
1423 static void stream_toggle_pause(VideoState *is)
1426 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1427 if (is->read_pause_return != AVERROR(ENOSYS)) {
1428 is->vidclk.paused = 0;
1430 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1432 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1433 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1436 static void toggle_pause(VideoState *is)
1438 stream_toggle_pause(is);
1442 static void toggle_mute(VideoState *is)
1444 is->muted = !is->muted;
1447 static void update_volume(VideoState *is, int sign, int step)
1449 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1452 static void step_to_next_frame(VideoState *is)
1454 /* if the stream is paused unpause it, then step */
1456 stream_toggle_pause(is);
1460 static double compute_target_delay(double delay, VideoState *is)
1462 double sync_threshold, diff = 0;
1464 /* update delay to follow master synchronisation source */
1465 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1466 /* if video is slave, we try to correct big delays by
1467 duplicating or deleting a frame */
1468 diff = get_clock(&is->vidclk) - get_master_clock(is);
1470 /* skip or repeat frame. We take into account the
1471 delay to compute the threshold. I still don't know
1472 if it is the best guess */
1473 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1474 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1475 if (diff <= -sync_threshold)
1476 delay = FFMAX(0, delay + diff);
1477 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1478 delay = delay + diff;
1479 else if (diff >= sync_threshold)
1484 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1490 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1491 if (vp->serial == nextvp->serial) {
1492 double duration = nextvp->pts - vp->pts;
1493 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1494 return vp->duration;
1502 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1503 /* update current video pts */
1504 set_clock(&is->vidclk, pts, serial);
1505 sync_clock_to_slave(&is->extclk, &is->vidclk);
1508 /* called to display each frame */
1509 static void video_refresh(void *opaque, double *remaining_time)
1511 VideoState *is = opaque;
1516 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1517 check_external_clock_speed(is);
1519 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1520 time = av_gettime_relative() / 1000000.0;
1521 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1523 is->last_vis_time = time;
1525 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1530 if (is->force_refresh)
1531 redisplay = frame_queue_prev(&is->pictq);
1533 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1534 // nothing to do, no picture to display in the queue
1536 double last_duration, duration, delay;
1539 /* dequeue the picture */
1540 lastvp = frame_queue_peek_last(&is->pictq);
1541 vp = frame_queue_peek(&is->pictq);
1543 if (vp->serial != is->videoq.serial) {
1544 frame_queue_next(&is->pictq);
1549 if (lastvp->serial != vp->serial && !redisplay)
1550 is->frame_timer = av_gettime_relative() / 1000000.0;
1555 /* compute nominal last_duration */
1556 last_duration = vp_duration(is, lastvp, vp);
1560 delay = compute_target_delay(last_duration, is);
1562 time= av_gettime_relative()/1000000.0;
1563 if (time < is->frame_timer + delay && !redisplay) {
1564 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1568 is->frame_timer += delay;
1569 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1570 is->frame_timer = time;
1572 SDL_LockMutex(is->pictq.mutex);
1573 if (!redisplay && !isnan(vp->pts))
1574 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1575 SDL_UnlockMutex(is->pictq.mutex);
1577 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1578 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1579 duration = vp_duration(is, vp, nextvp);
1580 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1582 is->frame_drops_late++;
1583 frame_queue_next(&is->pictq);
1589 if (is->subtitle_st) {
1590 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1591 sp = frame_queue_peek(&is->subpq);
1593 if (frame_queue_nb_remaining(&is->subpq) > 1)
1594 sp2 = frame_queue_peek_next(&is->subpq);
1598 if (sp->serial != is->subtitleq.serial
1599 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1600 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1602 frame_queue_next(&is->subpq);
1610 /* display picture */
1611 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1614 frame_queue_next(&is->pictq);
1616 if (is->step && !is->paused)
1617 stream_toggle_pause(is);
1620 is->force_refresh = 0;
1622 static int64_t last_time;
1624 int aqsize, vqsize, sqsize;
1627 cur_time = av_gettime_relative();
1628 if (!last_time || (cur_time - last_time) >= 30000) {
1633 aqsize = is->audioq.size;
1635 vqsize = is->videoq.size;
1636 if (is->subtitle_st)
1637 sqsize = is->subtitleq.size;
1639 if (is->audio_st && is->video_st)
1640 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1641 else if (is->video_st)
1642 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1643 else if (is->audio_st)
1644 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1645 av_log(NULL, AV_LOG_INFO,
1646 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1647 get_master_clock(is),
1648 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1650 is->frame_drops_early + is->frame_drops_late,
1654 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1655 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1657 last_time = cur_time;
1662 /* allocate a picture (needs to do that in main thread to avoid
1663 potential locking problems */
1664 static void alloc_picture(VideoState *is)
1669 vp = &is->pictq.queue[is->pictq.windex];
1673 video_open(is, 0, vp);
1675 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1678 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1679 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1680 /* SDL allocates a buffer smaller than requested if the video
1681 * overlay hardware is unable to support the requested size. */
1682 av_log(NULL, AV_LOG_FATAL,
1683 "Error: the video system does not support an image\n"
1684 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1685 "to reduce the image size.\n", vp->width, vp->height );
1689 SDL_LockMutex(is->pictq.mutex);
1691 SDL_CondSignal(is->pictq.cond);
1692 SDL_UnlockMutex(is->pictq.mutex);
1695 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1696 int i, width, height;
1698 for (i = 0; i < 3; i++) {
1705 if (bmp->pitches[i] > width) {
1706 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1707 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1713 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1717 #if defined(DEBUG_SYNC) && 0
1718 printf("frame_type=%c pts=%0.3f\n",
1719 av_get_picture_type_char(src_frame->pict_type), pts);
1722 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1725 vp->sar = src_frame->sample_aspect_ratio;
1727 /* alloc or resize hardware picture buffer */
1728 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1729 vp->width != src_frame->width ||
1730 vp->height != src_frame->height) {
1735 vp->width = src_frame->width;
1736 vp->height = src_frame->height;
1738 /* the allocation must be done in the main thread to avoid
1739 locking problems. */
1740 event.type = FF_ALLOC_EVENT;
1741 event.user.data1 = is;
1742 SDL_PushEvent(&event);
1744 /* wait until the picture is allocated */
1745 SDL_LockMutex(is->pictq.mutex);
1746 while (!vp->allocated && !is->videoq.abort_request) {
1747 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1749 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1750 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1751 while (!vp->allocated && !is->abort_request) {
1752 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1755 SDL_UnlockMutex(is->pictq.mutex);
1757 if (is->videoq.abort_request)
1761 /* if the frame is not skipped, then display it */
1763 AVPicture pict = { { 0 } };
1765 /* get a pointer on the bitmap */
1766 SDL_LockYUVOverlay (vp->bmp);
1768 pict.data[0] = vp->bmp->pixels[0];
1769 pict.data[1] = vp->bmp->pixels[2];
1770 pict.data[2] = vp->bmp->pixels[1];
1772 pict.linesize[0] = vp->bmp->pitches[0];
1773 pict.linesize[1] = vp->bmp->pitches[2];
1774 pict.linesize[2] = vp->bmp->pitches[1];
1777 // FIXME use direct rendering
1778 av_picture_copy(&pict, (AVPicture *)src_frame,
1779 src_frame->format, vp->width, vp->height);
1782 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1784 const AVClass *class = sws_get_class();
1785 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1786 AV_OPT_SEARCH_FAKE_OBJ);
1787 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1793 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1794 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1795 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1796 if (!is->img_convert_ctx) {
1797 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1800 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1801 0, vp->height, pict.data, pict.linesize);
1803 /* workaround SDL PITCH_WORKAROUND */
1804 duplicate_right_border_pixels(vp->bmp);
1805 /* update the bitmap content */
1806 SDL_UnlockYUVOverlay(vp->bmp);
1809 vp->duration = duration;
1811 vp->serial = serial;
1813 /* now we can update the picture count */
1814 frame_queue_push(&is->pictq);
1819 static int get_video_frame(VideoState *is, AVFrame *frame)
1823 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1829 if (frame->pts != AV_NOPTS_VALUE)
1830 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1832 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1834 is->viddec_width = frame->width;
1835 is->viddec_height = frame->height;
1837 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1838 if (frame->pts != AV_NOPTS_VALUE) {
1839 double diff = dpts - get_master_clock(is);
1840 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1841 diff - is->frame_last_filter_delay < 0 &&
1842 is->viddec.pkt_serial == is->vidclk.serial &&
1843 is->videoq.nb_packets) {
1844 is->frame_drops_early++;
1845 av_frame_unref(frame);
1856 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1857 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1860 int nb_filters = graph->nb_filters;
1861 AVFilterInOut *outputs = NULL, *inputs = NULL;
1864 outputs = avfilter_inout_alloc();
1865 inputs = avfilter_inout_alloc();
1866 if (!outputs || !inputs) {
1867 ret = AVERROR(ENOMEM);
1871 outputs->name = av_strdup("in");
1872 outputs->filter_ctx = source_ctx;
1873 outputs->pad_idx = 0;
1874 outputs->next = NULL;
1876 inputs->name = av_strdup("out");
1877 inputs->filter_ctx = sink_ctx;
1878 inputs->pad_idx = 0;
1879 inputs->next = NULL;
1881 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1884 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1888 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1889 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1890 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1892 ret = avfilter_graph_config(graph, NULL);
1894 avfilter_inout_free(&outputs);
1895 avfilter_inout_free(&inputs);
1899 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1901 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1902 char sws_flags_str[512] = "";
1903 char buffersrc_args[256];
1905 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1906 AVCodecContext *codec = is->video_st->codec;
1907 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1908 AVDictionaryEntry *e = NULL;
1910 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1911 if (!strcmp(e->key, "sws_flags")) {
1912 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1914 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1916 if (strlen(sws_flags_str))
1917 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1919 graph->scale_sws_opts = av_strdup(sws_flags_str);
1921 snprintf(buffersrc_args, sizeof(buffersrc_args),
1922 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1923 frame->width, frame->height, frame->format,
1924 is->video_st->time_base.num, is->video_st->time_base.den,
1925 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1926 if (fr.num && fr.den)
1927 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1929 if ((ret = avfilter_graph_create_filter(&filt_src,
1930 avfilter_get_by_name("buffer"),
1931 "ffplay_buffer", buffersrc_args, NULL,
1935 ret = avfilter_graph_create_filter(&filt_out,
1936 avfilter_get_by_name("buffersink"),
1937 "ffplay_buffersink", NULL, NULL, graph);
1941 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1944 last_filter = filt_out;
1946 /* Note: this macro adds a filter before the lastly added filter, so the
1947 * processing order of the filters is in reverse */
1948 #define INSERT_FILT(name, arg) do { \
1949 AVFilterContext *filt_ctx; \
1951 ret = avfilter_graph_create_filter(&filt_ctx, \
1952 avfilter_get_by_name(name), \
1953 "ffplay_" name, arg, NULL, graph); \
1957 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1961 last_filter = filt_ctx; \
1964 /* SDL YUV code is not handling odd width/height for some driver
1965 * combinations, therefore we crop the picture to an even width/height. */
1966 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1969 double theta = get_rotation(is->video_st);
1971 if (fabs(theta - 90) < 1.0) {
1972 INSERT_FILT("transpose", "clock");
1973 } else if (fabs(theta - 180) < 1.0) {
1974 INSERT_FILT("hflip", NULL);
1975 INSERT_FILT("vflip", NULL);
1976 } else if (fabs(theta - 270) < 1.0) {
1977 INSERT_FILT("transpose", "cclock");
1978 } else if (fabs(theta) > 1.0) {
1979 char rotate_buf[64];
1980 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1981 INSERT_FILT("rotate", rotate_buf);
1985 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1988 is->in_video_filter = filt_src;
1989 is->out_video_filter = filt_out;
1995 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1997 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1998 int sample_rates[2] = { 0, -1 };
1999 int64_t channel_layouts[2] = { 0, -1 };
2000 int channels[2] = { 0, -1 };
2001 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2002 char aresample_swr_opts[512] = "";
2003 AVDictionaryEntry *e = NULL;
2004 char asrc_args[256];
2007 avfilter_graph_free(&is->agraph);
2008 if (!(is->agraph = avfilter_graph_alloc()))
2009 return AVERROR(ENOMEM);
2011 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2012 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2013 if (strlen(aresample_swr_opts))
2014 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2015 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2017 ret = snprintf(asrc_args, sizeof(asrc_args),
2018 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2019 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2020 is->audio_filter_src.channels,
2021 1, is->audio_filter_src.freq);
2022 if (is->audio_filter_src.channel_layout)
2023 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2024 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2026 ret = avfilter_graph_create_filter(&filt_asrc,
2027 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2028 asrc_args, NULL, is->agraph);
2033 ret = avfilter_graph_create_filter(&filt_asink,
2034 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2035 NULL, NULL, is->agraph);
2039 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2041 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2044 if (force_output_format) {
2045 channel_layouts[0] = is->audio_tgt.channel_layout;
2046 channels [0] = is->audio_tgt.channels;
2047 sample_rates [0] = is->audio_tgt.freq;
2048 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2050 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2052 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2054 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2059 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2062 is->in_audio_filter = filt_asrc;
2063 is->out_audio_filter = filt_asink;
2067 avfilter_graph_free(&is->agraph);
2070 #endif /* CONFIG_AVFILTER */
2072 static int audio_thread(void *arg)
2074 VideoState *is = arg;
2075 AVFrame *frame = av_frame_alloc();
2078 int last_serial = -1;
2079 int64_t dec_channel_layout;
2087 return AVERROR(ENOMEM);
2090 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2094 tb = (AVRational){1, frame->sample_rate};
2097 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2100 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2101 frame->format, av_frame_get_channels(frame)) ||
2102 is->audio_filter_src.channel_layout != dec_channel_layout ||
2103 is->audio_filter_src.freq != frame->sample_rate ||
2104 is->auddec.pkt_serial != last_serial;
2107 char buf1[1024], buf2[1024];
2108 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2109 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2110 av_log(NULL, AV_LOG_DEBUG,
2111 "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",
2112 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2113 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2115 is->audio_filter_src.fmt = frame->format;
2116 is->audio_filter_src.channels = av_frame_get_channels(frame);
2117 is->audio_filter_src.channel_layout = dec_channel_layout;
2118 is->audio_filter_src.freq = frame->sample_rate;
2119 last_serial = is->auddec.pkt_serial;
2121 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2125 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2128 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2129 tb = is->out_audio_filter->inputs[0]->time_base;
2131 if (!(af = frame_queue_peek_writable(&is->sampq)))
2134 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2135 af->pos = av_frame_get_pkt_pos(frame);
2136 af->serial = is->auddec.pkt_serial;
2137 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2139 av_frame_move_ref(af->frame, frame);
2140 frame_queue_push(&is->sampq);
2143 if (is->audioq.serial != is->auddec.pkt_serial)
2146 if (ret == AVERROR_EOF)
2147 is->auddec.finished = is->auddec.pkt_serial;
2150 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2153 avfilter_graph_free(&is->agraph);
2155 av_frame_free(&frame);
2159 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2161 packet_queue_start(d->queue);
2162 d->decoder_tid = SDL_CreateThread(fn, arg);
2163 if (!d->decoder_tid) {
2164 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2165 return AVERROR(ENOMEM);
2170 static int video_thread(void *arg)
2172 VideoState *is = arg;
2173 AVFrame *frame = av_frame_alloc();
2177 AVRational tb = is->video_st->time_base;
2178 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2181 AVFilterGraph *graph = avfilter_graph_alloc();
2182 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2185 enum AVPixelFormat last_format = -2;
2186 int last_serial = -1;
2187 int last_vfilter_idx = 0;
2189 av_frame_free(&frame);
2190 return AVERROR(ENOMEM);
2197 avfilter_graph_free(&graph);
2199 return AVERROR(ENOMEM);
2203 ret = get_video_frame(is, frame);
2210 if ( last_w != frame->width
2211 || last_h != frame->height
2212 || last_format != frame->format
2213 || last_serial != is->viddec.pkt_serial
2214 || last_vfilter_idx != is->vfilter_idx) {
2215 av_log(NULL, AV_LOG_DEBUG,
2216 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2218 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2219 frame->width, frame->height,
2220 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2221 avfilter_graph_free(&graph);
2222 graph = avfilter_graph_alloc();
2223 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2225 event.type = FF_QUIT_EVENT;
2226 event.user.data1 = is;
2227 SDL_PushEvent(&event);
2230 filt_in = is->in_video_filter;
2231 filt_out = is->out_video_filter;
2232 last_w = frame->width;
2233 last_h = frame->height;
2234 last_format = frame->format;
2235 last_serial = is->viddec.pkt_serial;
2236 last_vfilter_idx = is->vfilter_idx;
2237 frame_rate = filt_out->inputs[0]->frame_rate;
2240 ret = av_buffersrc_add_frame(filt_in, frame);
2245 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2247 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2249 if (ret == AVERROR_EOF)
2250 is->viddec.finished = is->viddec.pkt_serial;
2255 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2256 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2257 is->frame_last_filter_delay = 0;
2258 tb = filt_out->inputs[0]->time_base;
2260 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2261 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2262 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2263 av_frame_unref(frame);
2273 avfilter_graph_free(&graph);
2275 av_frame_free(&frame);
2279 static int subtitle_thread(void *arg)
2281 VideoState *is = arg;
2288 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2291 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2296 if (got_subtitle && sp->sub.format == 0) {
2297 if (sp->sub.pts != AV_NOPTS_VALUE)
2298 pts = sp->sub.pts / (double)AV_TIME_BASE;
2300 sp->serial = is->subdec.pkt_serial;
2301 if (!(sp->subrects = av_mallocz_array(sp->sub.num_rects, sizeof(AVSubtitleRect*)))) {
2302 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subrects\n");
2306 for (i = 0; i < sp->sub.num_rects; i++)
2308 int in_w = sp->sub.rects[i]->w;
2309 int in_h = sp->sub.rects[i]->h;
2310 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2311 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2312 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2313 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2315 if (!(sp->subrects[i] = av_mallocz(sizeof(AVSubtitleRect))) ||
2316 av_image_alloc(sp->subrects[i]->data, sp->subrects[i]->linesize, out_w, out_h, AV_PIX_FMT_YUVA420P, 16) < 0) {
2317 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subtitle data\n");
2321 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2322 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2323 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2324 if (!is->sub_convert_ctx) {
2325 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2328 sws_scale(is->sub_convert_ctx,
2329 (void*)sp->sub.rects[i]->data, sp->sub.rects[i]->linesize,
2330 0, in_h, sp->subrects[i]->data, sp->subrects[i]->linesize);
2332 sp->subrects[i]->w = out_w;
2333 sp->subrects[i]->h = out_h;
2334 sp->subrects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2335 sp->subrects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2338 /* now we can update the picture count */
2339 frame_queue_push(&is->subpq);
2340 } else if (got_subtitle) {
2341 avsubtitle_free(&sp->sub);
2347 /* copy samples for viewing in editor window */
2348 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2352 size = samples_size / sizeof(short);
2354 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2357 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2359 is->sample_array_index += len;
2360 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2361 is->sample_array_index = 0;
2366 /* return the wanted number of samples to get better sync if sync_type is video
2367 * or external master clock */
2368 static int synchronize_audio(VideoState *is, int nb_samples)
2370 int wanted_nb_samples = nb_samples;
2372 /* if not master, then we try to remove or add samples to correct the clock */
2373 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2374 double diff, avg_diff;
2375 int min_nb_samples, max_nb_samples;
2377 diff = get_clock(&is->audclk) - get_master_clock(is);
2379 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2380 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2381 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2382 /* not enough measures to have a correct estimate */
2383 is->audio_diff_avg_count++;
2385 /* estimate the A-V difference */
2386 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2388 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2389 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2390 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2391 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2392 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2394 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2395 diff, avg_diff, wanted_nb_samples - nb_samples,
2396 is->audio_clock, is->audio_diff_threshold);
2399 /* too big difference : may be initial PTS errors, so
2401 is->audio_diff_avg_count = 0;
2402 is->audio_diff_cum = 0;
2406 return wanted_nb_samples;
2410 * Decode one audio frame and return its uncompressed size.
2412 * The processed audio frame is decoded, converted if required, and
2413 * stored in is->audio_buf, with size in bytes given by the return
2416 static int audio_decode_frame(VideoState *is)
2418 int data_size, resampled_data_size;
2419 int64_t dec_channel_layout;
2420 av_unused double audio_clock0;
2421 int wanted_nb_samples;
2429 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2430 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2435 if (!(af = frame_queue_peek_readable(&is->sampq)))
2437 frame_queue_next(&is->sampq);
2438 } while (af->serial != is->audioq.serial);
2440 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2441 af->frame->nb_samples,
2442 af->frame->format, 1);
2444 dec_channel_layout =
2445 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2446 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2447 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2449 if (af->frame->format != is->audio_src.fmt ||
2450 dec_channel_layout != is->audio_src.channel_layout ||
2451 af->frame->sample_rate != is->audio_src.freq ||
2452 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2453 swr_free(&is->swr_ctx);
2454 is->swr_ctx = swr_alloc_set_opts(NULL,
2455 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2456 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2458 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2459 av_log(NULL, AV_LOG_ERROR,
2460 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2461 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2462 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2463 swr_free(&is->swr_ctx);
2466 is->audio_src.channel_layout = dec_channel_layout;
2467 is->audio_src.channels = av_frame_get_channels(af->frame);
2468 is->audio_src.freq = af->frame->sample_rate;
2469 is->audio_src.fmt = af->frame->format;
2473 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2474 uint8_t **out = &is->audio_buf1;
2475 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2476 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2479 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2482 if (wanted_nb_samples != af->frame->nb_samples) {
2483 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2484 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2485 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2489 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2490 if (!is->audio_buf1)
2491 return AVERROR(ENOMEM);
2492 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2494 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2497 if (len2 == out_count) {
2498 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2499 if (swr_init(is->swr_ctx) < 0)
2500 swr_free(&is->swr_ctx);
2502 is->audio_buf = is->audio_buf1;
2503 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2505 is->audio_buf = af->frame->data[0];
2506 resampled_data_size = data_size;
2509 audio_clock0 = is->audio_clock;
2510 /* update the audio clock with the pts */
2511 if (!isnan(af->pts))
2512 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2514 is->audio_clock = NAN;
2515 is->audio_clock_serial = af->serial;
2518 static double last_clock;
2519 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2520 is->audio_clock - last_clock,
2521 is->audio_clock, audio_clock0);
2522 last_clock = is->audio_clock;
2525 return resampled_data_size;
2528 /* prepare a new audio buffer */
2529 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2531 VideoState *is = opaque;
2532 int audio_size, len1;
2534 audio_callback_time = av_gettime_relative();
2537 if (is->audio_buf_index >= is->audio_buf_size) {
2538 audio_size = audio_decode_frame(is);
2539 if (audio_size < 0) {
2540 /* if error, just output silence */
2541 is->audio_buf = is->silence_buf;
2542 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2544 if (is->show_mode != SHOW_MODE_VIDEO)
2545 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2546 is->audio_buf_size = audio_size;
2548 is->audio_buf_index = 0;
2550 len1 = is->audio_buf_size - is->audio_buf_index;
2553 if (!is->muted && is->audio_volume == SDL_MIX_MAXVOLUME)
2554 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2556 memset(stream, is->silence_buf[0], len1);
2558 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2562 is->audio_buf_index += len1;
2564 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2565 /* Let's assume the audio driver that is used by SDL has two periods. */
2566 if (!isnan(is->audio_clock)) {
2567 set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
2568 sync_clock_to_slave(&is->extclk, &is->audclk);
2572 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2574 SDL_AudioSpec wanted_spec, spec;
2576 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2577 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2578 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2580 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2582 wanted_nb_channels = atoi(env);
2583 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2585 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2586 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2587 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2589 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2590 wanted_spec.channels = wanted_nb_channels;
2591 wanted_spec.freq = wanted_sample_rate;
2592 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2593 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2596 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2597 next_sample_rate_idx--;
2598 wanted_spec.format = AUDIO_S16SYS;
2599 wanted_spec.silence = 0;
2600 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2601 wanted_spec.callback = sdl_audio_callback;
2602 wanted_spec.userdata = opaque;
2603 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2604 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2605 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2606 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2607 if (!wanted_spec.channels) {
2608 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2609 wanted_spec.channels = wanted_nb_channels;
2610 if (!wanted_spec.freq) {
2611 av_log(NULL, AV_LOG_ERROR,
2612 "No more combinations to try, audio open failed\n");
2616 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2618 if (spec.format != AUDIO_S16SYS) {
2619 av_log(NULL, AV_LOG_ERROR,
2620 "SDL advised audio format %d is not supported!\n", spec.format);
2623 if (spec.channels != wanted_spec.channels) {
2624 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2625 if (!wanted_channel_layout) {
2626 av_log(NULL, AV_LOG_ERROR,
2627 "SDL advised channel count %d is not supported!\n", spec.channels);
2632 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2633 audio_hw_params->freq = spec.freq;
2634 audio_hw_params->channel_layout = wanted_channel_layout;
2635 audio_hw_params->channels = spec.channels;
2636 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2637 audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
2638 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2639 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2645 /* open a given stream. Return 0 if OK */
2646 static int stream_component_open(VideoState *is, int stream_index)
2648 AVFormatContext *ic = is->ic;
2649 AVCodecContext *avctx;
2651 const char *forced_codec_name = NULL;
2653 AVDictionaryEntry *t = NULL;
2654 int sample_rate, nb_channels;
2655 int64_t channel_layout;
2657 int stream_lowres = lowres;
2659 if (stream_index < 0 || stream_index >= ic->nb_streams)
2661 avctx = ic->streams[stream_index]->codec;
2663 codec = avcodec_find_decoder(avctx->codec_id);
2665 switch(avctx->codec_type){
2666 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2667 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2668 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2670 if (forced_codec_name)
2671 codec = avcodec_find_decoder_by_name(forced_codec_name);
2673 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2674 "No codec could be found with name '%s'\n", forced_codec_name);
2675 else av_log(NULL, AV_LOG_WARNING,
2676 "No codec could be found with id %d\n", avctx->codec_id);
2680 avctx->codec_id = codec->id;
2681 if(stream_lowres > av_codec_get_max_lowres(codec)){
2682 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2683 av_codec_get_max_lowres(codec));
2684 stream_lowres = av_codec_get_max_lowres(codec);
2686 av_codec_set_lowres(avctx, stream_lowres);
2689 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2692 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2694 if(codec->capabilities & AV_CODEC_CAP_DR1)
2695 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2698 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2699 if (!av_dict_get(opts, "threads", NULL, 0))
2700 av_dict_set(&opts, "threads", "auto", 0);
2702 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2703 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2704 av_dict_set(&opts, "refcounted_frames", "1", 0);
2705 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2708 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2709 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2710 ret = AVERROR_OPTION_NOT_FOUND;
2715 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2716 switch (avctx->codec_type) {
2717 case AVMEDIA_TYPE_AUDIO:
2722 is->audio_filter_src.freq = avctx->sample_rate;
2723 is->audio_filter_src.channels = avctx->channels;
2724 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2725 is->audio_filter_src.fmt = avctx->sample_fmt;
2726 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2728 link = is->out_audio_filter->inputs[0];
2729 sample_rate = link->sample_rate;
2730 nb_channels = link->channels;
2731 channel_layout = link->channel_layout;
2734 sample_rate = avctx->sample_rate;
2735 nb_channels = avctx->channels;
2736 channel_layout = avctx->channel_layout;
2739 /* prepare audio output */
2740 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2742 is->audio_hw_buf_size = ret;
2743 is->audio_src = is->audio_tgt;
2744 is->audio_buf_size = 0;
2745 is->audio_buf_index = 0;
2747 /* init averaging filter */
2748 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2749 is->audio_diff_avg_count = 0;
2750 /* since we do not have a precise anough audio fifo fullness,
2751 we correct audio sync only if larger than this threshold */
2752 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2754 is->audio_stream = stream_index;
2755 is->audio_st = ic->streams[stream_index];
2757 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2758 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2759 is->auddec.start_pts = is->audio_st->start_time;
2760 is->auddec.start_pts_tb = is->audio_st->time_base;
2762 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2766 case AVMEDIA_TYPE_VIDEO:
2767 is->video_stream = stream_index;
2768 is->video_st = ic->streams[stream_index];
2770 is->viddec_width = avctx->width;
2771 is->viddec_height = avctx->height;
2773 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2774 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2776 is->queue_attachments_req = 1;
2778 case AVMEDIA_TYPE_SUBTITLE:
2779 is->subtitle_stream = stream_index;
2780 is->subtitle_st = ic->streams[stream_index];
2782 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2783 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2791 av_dict_free(&opts);
2796 static int decode_interrupt_cb(void *ctx)
2798 VideoState *is = ctx;
2799 return is->abort_request;
2802 static int is_realtime(AVFormatContext *s)
2804 if( !strcmp(s->iformat->name, "rtp")
2805 || !strcmp(s->iformat->name, "rtsp")
2806 || !strcmp(s->iformat->name, "sdp")
2810 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2811 || !strncmp(s->filename, "udp:", 4)
2818 /* this thread gets the stream from the disk or the network */
2819 static int read_thread(void *arg)
2821 VideoState *is = arg;
2822 AVFormatContext *ic = NULL;
2824 int st_index[AVMEDIA_TYPE_NB];
2825 AVPacket pkt1, *pkt = &pkt1;
2826 int64_t stream_start_time;
2827 int pkt_in_play_range = 0;
2828 AVDictionaryEntry *t;
2829 AVDictionary **opts;
2830 int orig_nb_streams;
2831 SDL_mutex *wait_mutex = SDL_CreateMutex();
2832 int scan_all_pmts_set = 0;
2836 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2837 ret = AVERROR(ENOMEM);
2841 memset(st_index, -1, sizeof(st_index));
2842 is->last_video_stream = is->video_stream = -1;
2843 is->last_audio_stream = is->audio_stream = -1;
2844 is->last_subtitle_stream = is->subtitle_stream = -1;
2847 ic = avformat_alloc_context();
2849 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2850 ret = AVERROR(ENOMEM);
2853 ic->interrupt_callback.callback = decode_interrupt_cb;
2854 ic->interrupt_callback.opaque = is;
2855 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2856 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2857 scan_all_pmts_set = 1;
2859 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2861 print_error(is->filename, err);
2865 if (scan_all_pmts_set)
2866 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2868 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2869 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2870 ret = AVERROR_OPTION_NOT_FOUND;
2876 ic->flags |= AVFMT_FLAG_GENPTS;
2878 av_format_inject_global_side_data(ic);
2880 opts = setup_find_stream_info_opts(ic, codec_opts);
2881 orig_nb_streams = ic->nb_streams;
2883 err = avformat_find_stream_info(ic, opts);
2885 for (i = 0; i < orig_nb_streams; i++)
2886 av_dict_free(&opts[i]);
2890 av_log(NULL, AV_LOG_WARNING,
2891 "%s: could not find codec parameters\n", is->filename);
2897 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2899 if (seek_by_bytes < 0)
2900 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2902 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2904 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2905 window_title = av_asprintf("%s - %s", t->value, input_filename);
2907 /* if seeking requested, we execute it */
2908 if (start_time != AV_NOPTS_VALUE) {
2911 timestamp = start_time;
2912 /* add the stream start time */
2913 if (ic->start_time != AV_NOPTS_VALUE)
2914 timestamp += ic->start_time;
2915 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2917 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2918 is->filename, (double)timestamp / AV_TIME_BASE);
2922 is->realtime = is_realtime(ic);
2925 av_dump_format(ic, 0, is->filename, 0);
2927 for (i = 0; i < ic->nb_streams; i++) {
2928 AVStream *st = ic->streams[i];
2929 enum AVMediaType type = st->codec->codec_type;
2930 st->discard = AVDISCARD_ALL;
2931 if (wanted_stream_spec[type] && st_index[type] == -1)
2932 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2935 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2936 if (wanted_stream_spec[i] && st_index[i] == -1) {
2937 av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i));
2938 st_index[i] = INT_MAX;
2943 st_index[AVMEDIA_TYPE_VIDEO] =
2944 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2945 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2947 st_index[AVMEDIA_TYPE_AUDIO] =
2948 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2949 st_index[AVMEDIA_TYPE_AUDIO],
2950 st_index[AVMEDIA_TYPE_VIDEO],
2952 if (!video_disable && !subtitle_disable)
2953 st_index[AVMEDIA_TYPE_SUBTITLE] =
2954 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2955 st_index[AVMEDIA_TYPE_SUBTITLE],
2956 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2957 st_index[AVMEDIA_TYPE_AUDIO] :
2958 st_index[AVMEDIA_TYPE_VIDEO]),
2961 is->show_mode = show_mode;
2962 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2963 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2964 AVCodecContext *avctx = st->codec;
2965 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2967 set_default_window_size(avctx->width, avctx->height, sar);
2970 /* open the streams */
2971 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2972 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2976 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2977 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2979 if (is->show_mode == SHOW_MODE_NONE)
2980 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2982 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2983 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2986 if (is->video_stream < 0 && is->audio_stream < 0) {
2987 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2993 if (infinite_buffer < 0 && is->realtime)
2994 infinite_buffer = 1;
2997 if (is->abort_request)
2999 if (is->paused != is->last_paused) {
3000 is->last_paused = is->paused;
3002 is->read_pause_return = av_read_pause(ic);
3006 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3008 (!strcmp(ic->iformat->name, "rtsp") ||
3009 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3010 /* wait 10 ms to avoid trying to get another packet */
3017 int64_t seek_target = is->seek_pos;
3018 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3019 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3020 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3021 // of the seek_pos/seek_rel variables
3023 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3025 av_log(NULL, AV_LOG_ERROR,
3026 "%s: error while seeking\n", is->ic->filename);
3028 if (is->audio_stream >= 0) {
3029 packet_queue_flush(&is->audioq);
3030 packet_queue_put(&is->audioq, &flush_pkt);
3032 if (is->subtitle_stream >= 0) {
3033 packet_queue_flush(&is->subtitleq);
3034 packet_queue_put(&is->subtitleq, &flush_pkt);
3036 if (is->video_stream >= 0) {
3037 packet_queue_flush(&is->videoq);
3038 packet_queue_put(&is->videoq, &flush_pkt);
3040 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3041 set_clock(&is->extclk, NAN, 0);
3043 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3047 is->queue_attachments_req = 1;
3050 step_to_next_frame(is);
3052 if (is->queue_attachments_req) {
3053 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3055 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3057 packet_queue_put(&is->videoq, ©);
3058 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3060 is->queue_attachments_req = 0;
3063 /* if the queue are full, no need to read more */
3064 if (infinite_buffer<1 &&
3065 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3066 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3067 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3068 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3069 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3071 SDL_LockMutex(wait_mutex);
3072 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3073 SDL_UnlockMutex(wait_mutex);
3077 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3078 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3079 if (loop != 1 && (!loop || --loop)) {
3080 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3081 } else if (autoexit) {
3086 ret = av_read_frame(ic, pkt);
3088 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3089 if (is->video_stream >= 0)
3090 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3091 if (is->audio_stream >= 0)
3092 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3093 if (is->subtitle_stream >= 0)
3094 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3097 if (ic->pb && ic->pb->error)
3099 SDL_LockMutex(wait_mutex);
3100 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3101 SDL_UnlockMutex(wait_mutex);
3106 /* check if packet is in play range specified by user, then queue, otherwise discard */
3107 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3108 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3109 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3110 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3111 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3112 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3113 <= ((double)duration / 1000000);
3114 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3115 packet_queue_put(&is->audioq, pkt);
3116 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3117 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3118 packet_queue_put(&is->videoq, pkt);
3119 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3120 packet_queue_put(&is->subtitleq, pkt);
3122 av_packet_unref(pkt);
3129 avformat_close_input(&ic);
3134 event.type = FF_QUIT_EVENT;
3135 event.user.data1 = is;
3136 SDL_PushEvent(&event);
3138 SDL_DestroyMutex(wait_mutex);
3142 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3146 is = av_mallocz(sizeof(VideoState));
3149 is->filename = av_strdup(filename);
3152 is->iformat = iformat;
3156 /* start video display */
3157 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3159 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3161 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3164 if (packet_queue_init(&is->videoq) < 0 ||
3165 packet_queue_init(&is->audioq) < 0 ||
3166 packet_queue_init(&is->subtitleq) < 0)
3169 if (!(is->continue_read_thread = SDL_CreateCond())) {
3170 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3174 init_clock(&is->vidclk, &is->videoq.serial);
3175 init_clock(&is->audclk, &is->audioq.serial);
3176 init_clock(&is->extclk, &is->extclk.serial);
3177 is->audio_clock_serial = -1;
3178 is->audio_volume = SDL_MIX_MAXVOLUME;
3180 is->av_sync_type = av_sync_type;
3181 is->read_tid = SDL_CreateThread(read_thread, is);
3182 if (!is->read_tid) {
3183 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3191 static void stream_cycle_channel(VideoState *is, int codec_type)
3193 AVFormatContext *ic = is->ic;
3194 int start_index, stream_index;
3197 AVProgram *p = NULL;
3198 int nb_streams = is->ic->nb_streams;
3200 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3201 start_index = is->last_video_stream;
3202 old_index = is->video_stream;
3203 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3204 start_index = is->last_audio_stream;
3205 old_index = is->audio_stream;
3207 start_index = is->last_subtitle_stream;
3208 old_index = is->subtitle_stream;
3210 stream_index = start_index;
3212 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3213 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3215 nb_streams = p->nb_stream_indexes;
3216 for (start_index = 0; start_index < nb_streams; start_index++)
3217 if (p->stream_index[start_index] == stream_index)
3219 if (start_index == nb_streams)
3221 stream_index = start_index;
3226 if (++stream_index >= nb_streams)
3228 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3231 is->last_subtitle_stream = -1;
3234 if (start_index == -1)
3238 if (stream_index == start_index)
3240 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3241 if (st->codec->codec_type == codec_type) {
3242 /* check that parameters are OK */
3243 switch (codec_type) {
3244 case AVMEDIA_TYPE_AUDIO:
3245 if (st->codec->sample_rate != 0 &&
3246 st->codec->channels != 0)
3249 case AVMEDIA_TYPE_VIDEO:
3250 case AVMEDIA_TYPE_SUBTITLE:
3258 if (p && stream_index != -1)
3259 stream_index = p->stream_index[stream_index];
3260 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3261 av_get_media_type_string(codec_type),
3265 stream_component_close(is, old_index);
3266 stream_component_open(is, stream_index);
3270 static void toggle_full_screen(VideoState *is)
3272 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3273 /* OS X needs to reallocate the SDL overlays */
3275 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3276 is->pictq.queue[i].reallocate = 1;
3278 is_full_screen = !is_full_screen;
3279 video_open(is, 1, NULL);
3282 static void toggle_audio_display(VideoState *is)
3284 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3285 int next = is->show_mode;
3287 next = (next + 1) % SHOW_MODE_NB;
3288 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3289 if (is->show_mode != next) {
3290 fill_rectangle(screen,
3291 is->xleft, is->ytop, is->width, is->height,
3293 is->force_refresh = 1;
3294 is->show_mode = next;
3298 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3299 double remaining_time = 0.0;
3301 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3302 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3306 if (remaining_time > 0.0)
3307 av_usleep((int64_t)(remaining_time * 1000000.0));
3308 remaining_time = REFRESH_RATE;
3309 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3310 video_refresh(is, &remaining_time);
3315 static void seek_chapter(VideoState *is, int incr)
3317 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3320 if (!is->ic->nb_chapters)
3323 /* find the current chapter */
3324 for (i = 0; i < is->ic->nb_chapters; i++) {
3325 AVChapter *ch = is->ic->chapters[i];
3326 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3334 if (i >= is->ic->nb_chapters)
3337 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3338 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3339 AV_TIME_BASE_Q), 0, 0);
3342 /* handle an event sent by the GUI */
3343 static void event_loop(VideoState *cur_stream)
3346 double incr, pos, frac;
3350 refresh_loop_wait_event(cur_stream, &event);
3351 switch (event.type) {
3353 if (exit_on_keydown) {
3354 do_exit(cur_stream);
3357 switch (event.key.keysym.sym) {
3360 do_exit(cur_stream);
3363 toggle_full_screen(cur_stream);
3364 cur_stream->force_refresh = 1;
3368 toggle_pause(cur_stream);
3371 toggle_mute(cur_stream);
3373 case SDLK_KP_MULTIPLY:
3375 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3377 case SDLK_KP_DIVIDE:
3379 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3381 case SDLK_s: // S: Step to next frame
3382 step_to_next_frame(cur_stream);
3385 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3388 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3391 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3392 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3393 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3396 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3400 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3401 if (++cur_stream->vfilter_idx >= nb_vfilters)
3402 cur_stream->vfilter_idx = 0;
3404 cur_stream->vfilter_idx = 0;
3405 toggle_audio_display(cur_stream);
3408 toggle_audio_display(cur_stream);
3412 if (cur_stream->ic->nb_chapters <= 1) {
3416 seek_chapter(cur_stream, 1);
3419 if (cur_stream->ic->nb_chapters <= 1) {
3423 seek_chapter(cur_stream, -1);
3437 if (seek_by_bytes) {
3439 if (pos < 0 && cur_stream->video_stream >= 0)
3440 pos = frame_queue_last_pos(&cur_stream->pictq);
3441 if (pos < 0 && cur_stream->audio_stream >= 0)
3442 pos = frame_queue_last_pos(&cur_stream->sampq);
3444 pos = avio_tell(cur_stream->ic->pb);
3445 if (cur_stream->ic->bit_rate)
3446 incr *= cur_stream->ic->bit_rate / 8.0;
3450 stream_seek(cur_stream, pos, incr, 1);
3452 pos = get_master_clock(cur_stream);
3454 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3456 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3457 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3458 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3465 case SDL_VIDEOEXPOSE:
3466 cur_stream->force_refresh = 1;
3468 case SDL_MOUSEBUTTONDOWN:
3469 if (exit_on_mousedown) {
3470 do_exit(cur_stream);
3473 case SDL_MOUSEMOTION:
3474 if (cursor_hidden) {
3478 cursor_last_shown = av_gettime_relative();
3479 if (event.type == SDL_MOUSEBUTTONDOWN) {
3482 if (event.motion.state != SDL_PRESSED)
3486 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3487 uint64_t size = avio_size(cur_stream->ic->pb);
3488 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3492 int tns, thh, tmm, tss;
3493 tns = cur_stream->ic->duration / 1000000LL;
3495 tmm = (tns % 3600) / 60;
3497 frac = x / cur_stream->width;
3500 mm = (ns % 3600) / 60;
3502 av_log(NULL, AV_LOG_INFO,
3503 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3504 hh, mm, ss, thh, tmm, tss);
3505 ts = frac * cur_stream->ic->duration;
3506 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3507 ts += cur_stream->ic->start_time;
3508 stream_seek(cur_stream, ts, 0, 0);
3511 case SDL_VIDEORESIZE:
3512 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3513 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3515 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3516 do_exit(cur_stream);
3518 screen_width = cur_stream->width = screen->w;
3519 screen_height = cur_stream->height = screen->h;
3520 cur_stream->force_refresh = 1;
3524 do_exit(cur_stream);
3526 case FF_ALLOC_EVENT:
3527 alloc_picture(event.user.data1);
3535 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3537 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3538 return opt_default(NULL, "video_size", arg);
3541 static int opt_width(void *optctx, const char *opt, const char *arg)
3543 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3547 static int opt_height(void *optctx, const char *opt, const char *arg)
3549 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3553 static int opt_format(void *optctx, const char *opt, const char *arg)
3555 file_iformat = av_find_input_format(arg);
3556 if (!file_iformat) {
3557 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3558 return AVERROR(EINVAL);
3563 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3565 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3566 return opt_default(NULL, "pixel_format", arg);
3569 static int opt_sync(void *optctx, const char *opt, const char *arg)
3571 if (!strcmp(arg, "audio"))
3572 av_sync_type = AV_SYNC_AUDIO_MASTER;
3573 else if (!strcmp(arg, "video"))
3574 av_sync_type = AV_SYNC_VIDEO_MASTER;
3575 else if (!strcmp(arg, "ext"))
3576 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3578 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3584 static int opt_seek(void *optctx, const char *opt, const char *arg)
3586 start_time = parse_time_or_die(opt, arg, 1);
3590 static int opt_duration(void *optctx, const char *opt, const char *arg)
3592 duration = parse_time_or_die(opt, arg, 1);
3596 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3598 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3599 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3600 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3601 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3605 static void opt_input_file(void *optctx, const char *filename)
3607 if (input_filename) {
3608 av_log(NULL, AV_LOG_FATAL,
3609 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3610 filename, input_filename);
3613 if (!strcmp(filename, "-"))
3615 input_filename = filename;
3618 static int opt_codec(void *optctx, const char *opt, const char *arg)
3620 const char *spec = strchr(opt, ':');
3622 av_log(NULL, AV_LOG_ERROR,
3623 "No media specifier was specified in '%s' in option '%s'\n",
3625 return AVERROR(EINVAL);
3629 case 'a' : audio_codec_name = arg; break;
3630 case 's' : subtitle_codec_name = arg; break;
3631 case 'v' : video_codec_name = arg; break;
3633 av_log(NULL, AV_LOG_ERROR,
3634 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3635 return AVERROR(EINVAL);
3642 static const OptionDef options[] = {
3643 #include "cmdutils_common_opts.h"
3644 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3645 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3646 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3647 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3648 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3649 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3650 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3651 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3652 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3653 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3654 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3655 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3656 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3657 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3658 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3659 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3660 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3661 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3662 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3663 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3664 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3665 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3666 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3667 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3668 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3669 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3670 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3671 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3672 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3674 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3675 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3677 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3678 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3679 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3680 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3681 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3682 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3683 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3684 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3685 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3689 static void show_usage(void)
3691 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3692 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3693 av_log(NULL, AV_LOG_INFO, "\n");
3696 void show_help_default(const char *opt, const char *arg)
3698 av_log_set_callback(log_callback_help);
3700 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3701 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3703 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3704 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3705 #if !CONFIG_AVFILTER
3706 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3708 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3710 printf("\nWhile playing:\n"
3712 "f toggle full screen\n"
3715 "9, 0 decrease and increase volume respectively\n"
3716 "/, * decrease and increase volume respectively\n"
3717 "a cycle audio channel in the current program\n"
3718 "v cycle video channel\n"
3719 "t cycle subtitle channel in the current program\n"
3721 "w cycle video filters or show modes\n"
3722 "s activate frame-step mode\n"
3723 "left/right seek backward/forward 10 seconds\n"
3724 "down/up seek backward/forward 1 minute\n"
3725 "page down/page up seek backward/forward 10 minutes\n"
3726 "mouse click seek to percentage in file corresponding to fraction of width\n"
3730 static int lockmgr(void **mtx, enum AVLockOp op)
3733 case AV_LOCK_CREATE:
3734 *mtx = SDL_CreateMutex();
3736 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3740 case AV_LOCK_OBTAIN:
3741 return !!SDL_LockMutex(*mtx);
3742 case AV_LOCK_RELEASE:
3743 return !!SDL_UnlockMutex(*mtx);
3744 case AV_LOCK_DESTROY:
3745 SDL_DestroyMutex(*mtx);
3751 /* Called from the main */
3752 int main(int argc, char **argv)
3756 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3758 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3759 parse_loglevel(argc, argv, options);
3761 /* register all codecs, demux and protocols */
3763 avdevice_register_all();
3766 avfilter_register_all();
3769 avformat_network_init();
3773 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3774 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3776 show_banner(argc, argv, options);
3778 parse_options(NULL, argc, argv, options, opt_input_file);
3780 if (!input_filename) {
3782 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3783 av_log(NULL, AV_LOG_FATAL,
3784 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3788 if (display_disable) {
3791 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3793 flags &= ~SDL_INIT_AUDIO;
3794 if (display_disable)
3795 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3796 #if !defined(_WIN32) && !defined(__APPLE__)
3797 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3799 if (SDL_Init (flags)) {
3800 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3801 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3805 if (!display_disable) {
3806 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3807 fs_screen_width = vi->current_w;
3808 fs_screen_height = vi->current_h;
3811 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3812 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3813 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3815 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3817 if (av_lockmgr_register(lockmgr)) {
3818 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3822 av_init_packet(&flush_pkt);
3823 flush_pkt.data = (uint8_t *)&flush_pkt;
3825 is = stream_open(input_filename, file_iformat);
3827 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");