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;
127 #define VIDEO_PICTURE_QUEUE_SIZE 3
128 #define SUBPICTURE_QUEUE_SIZE 16
129 #define SAMPLE_QUEUE_SIZE 9
130 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
132 typedef struct AudioParams {
135 int64_t channel_layout;
136 enum AVSampleFormat fmt;
141 typedef struct Clock {
142 double pts; /* clock base */
143 double pts_drift; /* clock base minus time at which we updated the clock */
146 int serial; /* clock is based on a packet with this serial */
148 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
151 /* Common struct for handling all types of decoded data and allocated render buffers. */
152 typedef struct Frame {
155 AVSubtitleRect **subrects; /* rescaled subtitle rectangles in yuva */
157 double pts; /* presentation timestamp for the frame */
158 double duration; /* estimated duration of the frame */
159 int64_t pos; /* byte position of the frame in the input file */
168 typedef struct FrameQueue {
169 Frame queue[FRAME_QUEUE_SIZE];
182 AV_SYNC_AUDIO_MASTER, /* default choice */
183 AV_SYNC_VIDEO_MASTER,
184 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
187 typedef struct Decoder {
191 AVCodecContext *avctx;
195 SDL_cond *empty_queue_cond;
197 AVRational start_pts_tb;
199 AVRational next_pts_tb;
200 SDL_Thread *decoder_tid;
203 typedef struct VideoState {
204 SDL_Thread *read_tid;
205 AVInputFormat *iformat;
210 int queue_attachments_req;
215 int read_pause_return;
239 int audio_clock_serial;
240 double audio_diff_cum; /* used for AV difference average computation */
241 double audio_diff_avg_coef;
242 double audio_diff_threshold;
243 int audio_diff_avg_count;
246 int audio_hw_buf_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 q->duration += pkt1->pkt.duration;
422 /* XXX: should duplicate packet data in DV case */
423 SDL_CondSignal(q->cond);
427 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
431 SDL_LockMutex(q->mutex);
432 ret = packet_queue_put_private(q, pkt);
433 SDL_UnlockMutex(q->mutex);
435 if (pkt != &flush_pkt && ret < 0)
436 av_packet_unref(pkt);
441 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
443 AVPacket pkt1, *pkt = &pkt1;
447 pkt->stream_index = stream_index;
448 return packet_queue_put(q, pkt);
451 /* packet queue handling */
452 static int packet_queue_init(PacketQueue *q)
454 memset(q, 0, sizeof(PacketQueue));
455 q->mutex = SDL_CreateMutex();
457 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
458 return AVERROR(ENOMEM);
460 q->cond = SDL_CreateCond();
462 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
463 return AVERROR(ENOMEM);
465 q->abort_request = 1;
469 static void packet_queue_flush(PacketQueue *q)
471 MyAVPacketList *pkt, *pkt1;
473 SDL_LockMutex(q->mutex);
474 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
476 av_packet_unref(&pkt->pkt);
484 SDL_UnlockMutex(q->mutex);
487 static void packet_queue_destroy(PacketQueue *q)
489 packet_queue_flush(q);
490 SDL_DestroyMutex(q->mutex);
491 SDL_DestroyCond(q->cond);
494 static void packet_queue_abort(PacketQueue *q)
496 SDL_LockMutex(q->mutex);
498 q->abort_request = 1;
500 SDL_CondSignal(q->cond);
502 SDL_UnlockMutex(q->mutex);
505 static void packet_queue_start(PacketQueue *q)
507 SDL_LockMutex(q->mutex);
508 q->abort_request = 0;
509 packet_queue_put_private(q, &flush_pkt);
510 SDL_UnlockMutex(q->mutex);
513 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
514 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
516 MyAVPacketList *pkt1;
519 SDL_LockMutex(q->mutex);
522 if (q->abort_request) {
529 q->first_pkt = pkt1->next;
533 q->size -= pkt1->pkt.size + sizeof(*pkt1);
534 q->duration -= pkt1->pkt.duration;
537 *serial = pkt1->serial;
545 SDL_CondWait(q->cond, q->mutex);
548 SDL_UnlockMutex(q->mutex);
552 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
553 memset(d, 0, sizeof(Decoder));
556 d->empty_queue_cond = empty_queue_cond;
557 d->start_pts = AV_NOPTS_VALUE;
560 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
566 if (d->queue->abort_request)
569 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
572 if (d->queue->nb_packets == 0)
573 SDL_CondSignal(d->empty_queue_cond);
574 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
576 if (pkt.data == flush_pkt.data) {
577 avcodec_flush_buffers(d->avctx);
579 d->next_pts = d->start_pts;
580 d->next_pts_tb = d->start_pts_tb;
582 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
583 av_packet_unref(&d->pkt);
584 d->pkt_temp = d->pkt = pkt;
585 d->packet_pending = 1;
588 switch (d->avctx->codec_type) {
589 case AVMEDIA_TYPE_VIDEO:
590 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
592 if (decoder_reorder_pts == -1) {
593 frame->pts = av_frame_get_best_effort_timestamp(frame);
594 } else if (decoder_reorder_pts) {
595 frame->pts = frame->pkt_pts;
597 frame->pts = frame->pkt_dts;
601 case AVMEDIA_TYPE_AUDIO:
602 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
604 AVRational tb = (AVRational){1, frame->sample_rate};
605 if (frame->pts != AV_NOPTS_VALUE)
606 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
607 else if (frame->pkt_pts != AV_NOPTS_VALUE)
608 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
609 else if (d->next_pts != AV_NOPTS_VALUE)
610 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
611 if (frame->pts != AV_NOPTS_VALUE) {
612 d->next_pts = frame->pts + frame->nb_samples;
617 case AVMEDIA_TYPE_SUBTITLE:
618 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
623 d->packet_pending = 0;
626 d->pkt_temp.pts = AV_NOPTS_VALUE;
627 if (d->pkt_temp.data) {
628 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
629 ret = d->pkt_temp.size;
630 d->pkt_temp.data += ret;
631 d->pkt_temp.size -= ret;
632 if (d->pkt_temp.size <= 0)
633 d->packet_pending = 0;
636 d->packet_pending = 0;
637 d->finished = d->pkt_serial;
641 } while (!got_frame && !d->finished);
646 static void decoder_destroy(Decoder *d) {
647 av_packet_unref(&d->pkt);
648 avcodec_free_context(&d->avctx);
651 static void frame_queue_unref_item(Frame *vp)
654 for (i = 0; i < vp->sub.num_rects; i++) {
655 av_freep(&vp->subrects[i]->data[0]);
656 av_freep(&vp->subrects[i]);
658 av_freep(&vp->subrects);
659 av_frame_unref(vp->frame);
660 avsubtitle_free(&vp->sub);
663 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
666 memset(f, 0, sizeof(FrameQueue));
667 if (!(f->mutex = SDL_CreateMutex())) {
668 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
669 return AVERROR(ENOMEM);
671 if (!(f->cond = SDL_CreateCond())) {
672 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
673 return AVERROR(ENOMEM);
676 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
677 f->keep_last = !!keep_last;
678 for (i = 0; i < f->max_size; i++)
679 if (!(f->queue[i].frame = av_frame_alloc()))
680 return AVERROR(ENOMEM);
684 static void frame_queue_destory(FrameQueue *f)
687 for (i = 0; i < f->max_size; i++) {
688 Frame *vp = &f->queue[i];
689 frame_queue_unref_item(vp);
690 av_frame_free(&vp->frame);
693 SDL_DestroyMutex(f->mutex);
694 SDL_DestroyCond(f->cond);
697 static void frame_queue_signal(FrameQueue *f)
699 SDL_LockMutex(f->mutex);
700 SDL_CondSignal(f->cond);
701 SDL_UnlockMutex(f->mutex);
704 static Frame *frame_queue_peek(FrameQueue *f)
706 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
709 static Frame *frame_queue_peek_next(FrameQueue *f)
711 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
714 static Frame *frame_queue_peek_last(FrameQueue *f)
716 return &f->queue[f->rindex];
719 static Frame *frame_queue_peek_writable(FrameQueue *f)
721 /* wait until we have space to put a new frame */
722 SDL_LockMutex(f->mutex);
723 while (f->size >= f->max_size &&
724 !f->pktq->abort_request) {
725 SDL_CondWait(f->cond, f->mutex);
727 SDL_UnlockMutex(f->mutex);
729 if (f->pktq->abort_request)
732 return &f->queue[f->windex];
735 static Frame *frame_queue_peek_readable(FrameQueue *f)
737 /* wait until we have a readable a new frame */
738 SDL_LockMutex(f->mutex);
739 while (f->size - f->rindex_shown <= 0 &&
740 !f->pktq->abort_request) {
741 SDL_CondWait(f->cond, f->mutex);
743 SDL_UnlockMutex(f->mutex);
745 if (f->pktq->abort_request)
748 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
751 static void frame_queue_push(FrameQueue *f)
753 if (++f->windex == f->max_size)
755 SDL_LockMutex(f->mutex);
757 SDL_CondSignal(f->cond);
758 SDL_UnlockMutex(f->mutex);
761 static void frame_queue_next(FrameQueue *f)
763 if (f->keep_last && !f->rindex_shown) {
767 frame_queue_unref_item(&f->queue[f->rindex]);
768 if (++f->rindex == f->max_size)
770 SDL_LockMutex(f->mutex);
772 SDL_CondSignal(f->cond);
773 SDL_UnlockMutex(f->mutex);
776 /* return the number of undisplayed frames in the queue */
777 static int frame_queue_nb_remaining(FrameQueue *f)
779 return f->size - f->rindex_shown;
782 /* return last shown position */
783 static int64_t frame_queue_last_pos(FrameQueue *f)
785 Frame *fp = &f->queue[f->rindex];
786 if (f->rindex_shown && fp->serial == f->pktq->serial)
792 static void decoder_abort(Decoder *d, FrameQueue *fq)
794 packet_queue_abort(d->queue);
795 frame_queue_signal(fq);
796 SDL_WaitThread(d->decoder_tid, NULL);
797 d->decoder_tid = NULL;
798 packet_queue_flush(d->queue);
801 static inline void fill_rectangle(SDL_Surface *screen,
802 int x, int y, int w, int h, int color, int update)
809 SDL_FillRect(screen, &rect, color);
810 if (update && w > 0 && h > 0)
811 SDL_UpdateRect(screen, x, y, w, h);
814 /* draw only the border of a rectangle */
815 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
819 /* fill the background */
823 w2 = width - (x + w);
829 h2 = height - (y + h);
832 fill_rectangle(screen,
836 fill_rectangle(screen,
837 xleft + width - w2, ytop,
840 fill_rectangle(screen,
844 fill_rectangle(screen,
845 xleft + w1, ytop + height - h2,
850 #define ALPHA_BLEND(a, oldp, newp, s)\
851 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
857 static void blend_subrect(uint8_t **data, int *linesize, const AVSubtitleRect *rect, int imgw, int imgh)
859 int x, y, Y, U, V, A;
860 uint8_t *lum, *cb, *cr;
861 int dstx, dsty, dstw, dsth;
862 const AVSubtitleRect *src = rect;
864 dstw = av_clip(rect->w, 0, imgw);
865 dsth = av_clip(rect->h, 0, imgh);
866 dstx = av_clip(rect->x, 0, imgw - dstw);
867 dsty = av_clip(rect->y, 0, imgh - dsth);
868 lum = data[0] + dstx + dsty * linesize[0];
869 cb = data[1] + dstx/2 + (dsty >> 1) * linesize[1];
870 cr = data[2] + dstx/2 + (dsty >> 1) * linesize[2];
872 for (y = 0; y<dsth; y++) {
873 for (x = 0; x<dstw; x++) {
874 Y = src->data[0][x + y*src->linesize[0]];
875 A = src->data[3][x + y*src->linesize[3]];
876 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
879 lum += linesize[0] - dstw;
882 for (y = 0; y<dsth/2; y++) {
883 for (x = 0; x<dstw/2; x++) {
884 U = src->data[1][x + y*src->linesize[1]];
885 V = src->data[2][x + y*src->linesize[2]];
886 A = src->data[3][2*x + 2*y *src->linesize[3]]
887 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
888 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
889 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
890 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
891 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
895 cb += linesize[1] - dstw/2;
896 cr += linesize[2] - dstw/2;
900 static void free_picture(Frame *vp)
903 SDL_FreeYUVOverlay(vp->bmp);
908 static void calculate_display_rect(SDL_Rect *rect,
909 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
910 int pic_width, int pic_height, AVRational pic_sar)
913 int width, height, x, y;
915 if (pic_sar.num == 0)
918 aspect_ratio = av_q2d(pic_sar);
920 if (aspect_ratio <= 0.0)
922 aspect_ratio *= (float)pic_width / (float)pic_height;
924 /* XXX: we suppose the screen has a 1.0 pixel ratio */
926 width = lrint(height * aspect_ratio) & ~1;
927 if (width > scr_width) {
929 height = lrint(width / aspect_ratio) & ~1;
931 x = (scr_width - width) / 2;
932 y = (scr_height - height) / 2;
933 rect->x = scr_xleft + x;
934 rect->y = scr_ytop + y;
935 rect->w = FFMAX(width, 1);
936 rect->h = FFMAX(height, 1);
939 static void video_image_display(VideoState *is)
946 vp = frame_queue_peek_last(&is->pictq);
948 if (is->subtitle_st) {
949 if (frame_queue_nb_remaining(&is->subpq) > 0) {
950 sp = frame_queue_peek(&is->subpq);
952 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
956 SDL_LockYUVOverlay (vp->bmp);
958 data[0] = vp->bmp->pixels[0];
959 data[1] = vp->bmp->pixels[2];
960 data[2] = vp->bmp->pixels[1];
962 linesize[0] = vp->bmp->pitches[0];
963 linesize[1] = vp->bmp->pitches[2];
964 linesize[2] = vp->bmp->pitches[1];
966 for (i = 0; i < sp->sub.num_rects; i++)
967 blend_subrect(data, linesize, sp->subrects[i],
968 vp->bmp->w, vp->bmp->h);
970 SDL_UnlockYUVOverlay (vp->bmp);
975 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
977 SDL_DisplayYUVOverlay(vp->bmp, &rect);
979 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) {
980 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
981 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
982 is->last_display_rect = rect;
987 static inline int compute_mod(int a, int b)
989 return a < 0 ? a%b + b : a%b;
992 static void video_audio_display(VideoState *s)
994 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
995 int ch, channels, h, h2, bgcolor, fgcolor;
997 int rdft_bits, nb_freq;
999 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1001 nb_freq = 1 << (rdft_bits - 1);
1003 /* compute display index : center on currently output samples */
1004 channels = s->audio_tgt.channels;
1005 nb_display_channels = channels;
1007 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1009 delay = s->audio_write_buf_size;
1012 /* to be more precise, we take into account the time spent since
1013 the last buffer computation */
1014 if (audio_callback_time) {
1015 time_diff = av_gettime_relative() - audio_callback_time;
1016 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1019 delay += 2 * data_used;
1020 if (delay < data_used)
1023 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1024 if (s->show_mode == SHOW_MODE_WAVES) {
1026 for (i = 0; i < 1000; i += channels) {
1027 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1028 int a = s->sample_array[idx];
1029 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1030 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1031 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1033 if (h < score && (b ^ c) < 0) {
1040 s->last_i_start = i_start;
1042 i_start = s->last_i_start;
1045 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1046 if (s->show_mode == SHOW_MODE_WAVES) {
1047 fill_rectangle(screen,
1048 s->xleft, s->ytop, s->width, s->height,
1051 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1053 /* total height for one channel */
1054 h = s->height / nb_display_channels;
1055 /* graph height / 2 */
1057 for (ch = 0; ch < nb_display_channels; ch++) {
1059 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1060 for (x = 0; x < s->width; x++) {
1061 y = (s->sample_array[i] * h2) >> 15;
1068 fill_rectangle(screen,
1069 s->xleft + x, ys, 1, y,
1072 if (i >= SAMPLE_ARRAY_SIZE)
1073 i -= SAMPLE_ARRAY_SIZE;
1077 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1079 for (ch = 1; ch < nb_display_channels; ch++) {
1080 y = s->ytop + ch * h;
1081 fill_rectangle(screen,
1082 s->xleft, y, s->width, 1,
1085 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1087 nb_display_channels= FFMIN(nb_display_channels, 2);
1088 if (rdft_bits != s->rdft_bits) {
1089 av_rdft_end(s->rdft);
1090 av_free(s->rdft_data);
1091 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1092 s->rdft_bits = rdft_bits;
1093 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1095 if (!s->rdft || !s->rdft_data){
1096 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1097 s->show_mode = SHOW_MODE_WAVES;
1100 for (ch = 0; ch < nb_display_channels; ch++) {
1101 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1103 for (x = 0; x < 2 * nb_freq; x++) {
1104 double w = (x-nb_freq) * (1.0 / nb_freq);
1105 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1107 if (i >= SAMPLE_ARRAY_SIZE)
1108 i -= SAMPLE_ARRAY_SIZE;
1110 av_rdft_calc(s->rdft, data[ch]);
1112 /* Least efficient way to do this, we should of course
1113 * directly access it but it is more than fast enough. */
1114 for (y = 0; y < s->height; y++) {
1115 double w = 1 / sqrt(nb_freq);
1116 int a = sqrt(w * hypot(data[0][2 * y + 0], data[0][2 * y + 1]));
1117 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1121 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1123 fill_rectangle(screen,
1124 s->xpos, s->height-y, 1, 1,
1128 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1131 if (s->xpos >= s->width)
1136 static void stream_component_close(VideoState *is, int stream_index)
1138 AVFormatContext *ic = is->ic;
1139 AVCodecParameters *codecpar;
1141 if (stream_index < 0 || stream_index >= ic->nb_streams)
1143 codecpar = ic->streams[stream_index]->codecpar;
1145 switch (codecpar->codec_type) {
1146 case AVMEDIA_TYPE_AUDIO:
1147 decoder_abort(&is->auddec, &is->sampq);
1149 decoder_destroy(&is->auddec);
1150 swr_free(&is->swr_ctx);
1151 av_freep(&is->audio_buf1);
1152 is->audio_buf1_size = 0;
1153 is->audio_buf = NULL;
1156 av_rdft_end(is->rdft);
1157 av_freep(&is->rdft_data);
1162 case AVMEDIA_TYPE_VIDEO:
1163 decoder_abort(&is->viddec, &is->pictq);
1164 decoder_destroy(&is->viddec);
1166 case AVMEDIA_TYPE_SUBTITLE:
1167 decoder_abort(&is->subdec, &is->subpq);
1168 decoder_destroy(&is->subdec);
1174 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1175 switch (codecpar->codec_type) {
1176 case AVMEDIA_TYPE_AUDIO:
1177 is->audio_st = NULL;
1178 is->audio_stream = -1;
1180 case AVMEDIA_TYPE_VIDEO:
1181 is->video_st = NULL;
1182 is->video_stream = -1;
1184 case AVMEDIA_TYPE_SUBTITLE:
1185 is->subtitle_st = NULL;
1186 is->subtitle_stream = -1;
1193 static void stream_close(VideoState *is)
1195 /* XXX: use a special url_shutdown call to abort parse cleanly */
1196 is->abort_request = 1;
1197 SDL_WaitThread(is->read_tid, NULL);
1199 /* close each stream */
1200 if (is->audio_stream >= 0)
1201 stream_component_close(is, is->audio_stream);
1202 if (is->video_stream >= 0)
1203 stream_component_close(is, is->video_stream);
1204 if (is->subtitle_stream >= 0)
1205 stream_component_close(is, is->subtitle_stream);
1207 avformat_close_input(&is->ic);
1209 packet_queue_destroy(&is->videoq);
1210 packet_queue_destroy(&is->audioq);
1211 packet_queue_destroy(&is->subtitleq);
1213 /* free all pictures */
1214 frame_queue_destory(&is->pictq);
1215 frame_queue_destory(&is->sampq);
1216 frame_queue_destory(&is->subpq);
1217 SDL_DestroyCond(is->continue_read_thread);
1218 #if !CONFIG_AVFILTER
1219 sws_freeContext(is->img_convert_ctx);
1221 sws_freeContext(is->sub_convert_ctx);
1222 av_free(is->filename);
1226 static void do_exit(VideoState *is)
1231 av_lockmgr_register(NULL);
1234 av_freep(&vfilters_list);
1236 avformat_network_deinit();
1240 av_log(NULL, AV_LOG_QUIET, "%s", "");
1244 static void sigterm_handler(int sig)
1249 static void set_default_window_size(int width, int height, AVRational sar)
1252 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1253 default_width = rect.w;
1254 default_height = rect.h;
1257 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1259 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1262 if (is_full_screen) flags |= SDL_FULLSCREEN;
1263 else flags |= SDL_RESIZABLE;
1265 if (vp && vp->width)
1266 set_default_window_size(vp->width, vp->height, vp->sar);
1268 if (is_full_screen && fs_screen_width) {
1269 w = fs_screen_width;
1270 h = fs_screen_height;
1271 } else if (!is_full_screen && screen_width) {
1278 w = FFMIN(16383, w);
1279 if (screen && is->width == screen->w && screen->w == w
1280 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1282 screen = SDL_SetVideoMode(w, h, 0, flags);
1284 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1288 window_title = input_filename;
1289 SDL_WM_SetCaption(window_title, window_title);
1291 is->width = screen->w;
1292 is->height = screen->h;
1297 /* display the current picture, if any */
1298 static void video_display(VideoState *is)
1301 video_open(is, 0, NULL);
1302 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1303 video_audio_display(is);
1304 else if (is->video_st)
1305 video_image_display(is);
1308 static double get_clock(Clock *c)
1310 if (*c->queue_serial != c->serial)
1315 double time = av_gettime_relative() / 1000000.0;
1316 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1320 static void set_clock_at(Clock *c, double pts, int serial, double time)
1323 c->last_updated = time;
1324 c->pts_drift = c->pts - time;
1328 static void set_clock(Clock *c, double pts, int serial)
1330 double time = av_gettime_relative() / 1000000.0;
1331 set_clock_at(c, pts, serial, time);
1334 static void set_clock_speed(Clock *c, double speed)
1336 set_clock(c, get_clock(c), c->serial);
1340 static void init_clock(Clock *c, int *queue_serial)
1344 c->queue_serial = queue_serial;
1345 set_clock(c, NAN, -1);
1348 static void sync_clock_to_slave(Clock *c, Clock *slave)
1350 double clock = get_clock(c);
1351 double slave_clock = get_clock(slave);
1352 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1353 set_clock(c, slave_clock, slave->serial);
1356 static int get_master_sync_type(VideoState *is) {
1357 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1359 return AV_SYNC_VIDEO_MASTER;
1361 return AV_SYNC_AUDIO_MASTER;
1362 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1364 return AV_SYNC_AUDIO_MASTER;
1366 return AV_SYNC_EXTERNAL_CLOCK;
1368 return AV_SYNC_EXTERNAL_CLOCK;
1372 /* get the current master clock value */
1373 static double get_master_clock(VideoState *is)
1377 switch (get_master_sync_type(is)) {
1378 case AV_SYNC_VIDEO_MASTER:
1379 val = get_clock(&is->vidclk);
1381 case AV_SYNC_AUDIO_MASTER:
1382 val = get_clock(&is->audclk);
1385 val = get_clock(&is->extclk);
1391 static void check_external_clock_speed(VideoState *is) {
1392 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1393 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1394 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1395 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1396 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1397 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1399 double speed = is->extclk.speed;
1401 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1405 /* seek in the stream */
1406 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1408 if (!is->seek_req) {
1411 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1413 is->seek_flags |= AVSEEK_FLAG_BYTE;
1415 SDL_CondSignal(is->continue_read_thread);
1419 /* pause or resume the video */
1420 static void stream_toggle_pause(VideoState *is)
1423 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1424 if (is->read_pause_return != AVERROR(ENOSYS)) {
1425 is->vidclk.paused = 0;
1427 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1429 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1430 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1433 static void toggle_pause(VideoState *is)
1435 stream_toggle_pause(is);
1439 static void toggle_mute(VideoState *is)
1441 is->muted = !is->muted;
1444 static void update_volume(VideoState *is, int sign, int step)
1446 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1449 static void step_to_next_frame(VideoState *is)
1451 /* if the stream is paused unpause it, then step */
1453 stream_toggle_pause(is);
1457 static double compute_target_delay(double delay, VideoState *is)
1459 double sync_threshold, diff = 0;
1461 /* update delay to follow master synchronisation source */
1462 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1463 /* if video is slave, we try to correct big delays by
1464 duplicating or deleting a frame */
1465 diff = get_clock(&is->vidclk) - get_master_clock(is);
1467 /* skip or repeat frame. We take into account the
1468 delay to compute the threshold. I still don't know
1469 if it is the best guess */
1470 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1471 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1472 if (diff <= -sync_threshold)
1473 delay = FFMAX(0, delay + diff);
1474 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1475 delay = delay + diff;
1476 else if (diff >= sync_threshold)
1481 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1487 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1488 if (vp->serial == nextvp->serial) {
1489 double duration = nextvp->pts - vp->pts;
1490 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1491 return vp->duration;
1499 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1500 /* update current video pts */
1501 set_clock(&is->vidclk, pts, serial);
1502 sync_clock_to_slave(&is->extclk, &is->vidclk);
1505 /* called to display each frame */
1506 static void video_refresh(void *opaque, double *remaining_time)
1508 VideoState *is = opaque;
1513 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1514 check_external_clock_speed(is);
1516 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1517 time = av_gettime_relative() / 1000000.0;
1518 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1520 is->last_vis_time = time;
1522 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1527 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1528 // nothing to do, no picture to display in the queue
1530 double last_duration, duration, delay;
1533 /* dequeue the picture */
1534 lastvp = frame_queue_peek_last(&is->pictq);
1535 vp = frame_queue_peek(&is->pictq);
1537 if (vp->serial != is->videoq.serial) {
1538 frame_queue_next(&is->pictq);
1542 if (lastvp->serial != vp->serial)
1543 is->frame_timer = av_gettime_relative() / 1000000.0;
1548 /* compute nominal last_duration */
1549 last_duration = vp_duration(is, lastvp, vp);
1550 delay = compute_target_delay(last_duration, is);
1552 time= av_gettime_relative()/1000000.0;
1553 if (time < is->frame_timer + delay) {
1554 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1558 is->frame_timer += delay;
1559 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1560 is->frame_timer = time;
1562 SDL_LockMutex(is->pictq.mutex);
1563 if (!isnan(vp->pts))
1564 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1565 SDL_UnlockMutex(is->pictq.mutex);
1567 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1568 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1569 duration = vp_duration(is, vp, nextvp);
1570 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1571 is->frame_drops_late++;
1572 frame_queue_next(&is->pictq);
1577 if (is->subtitle_st) {
1578 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1579 sp = frame_queue_peek(&is->subpq);
1581 if (frame_queue_nb_remaining(&is->subpq) > 1)
1582 sp2 = frame_queue_peek_next(&is->subpq);
1586 if (sp->serial != is->subtitleq.serial
1587 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1588 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1590 frame_queue_next(&is->subpq);
1597 frame_queue_next(&is->pictq);
1598 is->force_refresh = 1;
1600 if (is->step && !is->paused)
1601 stream_toggle_pause(is);
1604 /* display picture */
1605 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1608 is->force_refresh = 0;
1610 static int64_t last_time;
1612 int aqsize, vqsize, sqsize;
1615 cur_time = av_gettime_relative();
1616 if (!last_time || (cur_time - last_time) >= 30000) {
1621 aqsize = is->audioq.size;
1623 vqsize = is->videoq.size;
1624 if (is->subtitle_st)
1625 sqsize = is->subtitleq.size;
1627 if (is->audio_st && is->video_st)
1628 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1629 else if (is->video_st)
1630 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1631 else if (is->audio_st)
1632 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1633 av_log(NULL, AV_LOG_INFO,
1634 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1635 get_master_clock(is),
1636 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1638 is->frame_drops_early + is->frame_drops_late,
1642 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1643 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1645 last_time = cur_time;
1650 /* allocate a picture (needs to do that in main thread to avoid
1651 potential locking problems */
1652 static void alloc_picture(VideoState *is)
1657 vp = &is->pictq.queue[is->pictq.windex];
1661 video_open(is, 0, vp);
1663 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1666 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1667 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1668 /* SDL allocates a buffer smaller than requested if the video
1669 * overlay hardware is unable to support the requested size. */
1670 av_log(NULL, AV_LOG_FATAL,
1671 "Error: the video system does not support an image\n"
1672 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1673 "to reduce the image size.\n", vp->width, vp->height );
1677 SDL_LockMutex(is->pictq.mutex);
1679 SDL_CondSignal(is->pictq.cond);
1680 SDL_UnlockMutex(is->pictq.mutex);
1683 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1684 int i, width, height;
1686 for (i = 0; i < 3; i++) {
1693 if (bmp->pitches[i] > width) {
1694 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1695 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1701 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1705 #if defined(DEBUG_SYNC)
1706 printf("frame_type=%c pts=%0.3f\n",
1707 av_get_picture_type_char(src_frame->pict_type), pts);
1710 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1713 vp->sar = src_frame->sample_aspect_ratio;
1715 /* alloc or resize hardware picture buffer */
1716 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1717 vp->width != src_frame->width ||
1718 vp->height != src_frame->height) {
1723 vp->width = src_frame->width;
1724 vp->height = src_frame->height;
1726 /* the allocation must be done in the main thread to avoid
1727 locking problems. */
1728 event.type = FF_ALLOC_EVENT;
1729 event.user.data1 = is;
1730 SDL_PushEvent(&event);
1732 /* wait until the picture is allocated */
1733 SDL_LockMutex(is->pictq.mutex);
1734 while (!vp->allocated && !is->videoq.abort_request) {
1735 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1737 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1738 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1739 while (!vp->allocated && !is->abort_request) {
1740 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1743 SDL_UnlockMutex(is->pictq.mutex);
1745 if (is->videoq.abort_request)
1749 /* if the frame is not skipped, then display it */
1754 /* get a pointer on the bitmap */
1755 SDL_LockYUVOverlay (vp->bmp);
1757 data[0] = vp->bmp->pixels[0];
1758 data[1] = vp->bmp->pixels[2];
1759 data[2] = vp->bmp->pixels[1];
1761 linesize[0] = vp->bmp->pitches[0];
1762 linesize[1] = vp->bmp->pitches[2];
1763 linesize[2] = vp->bmp->pitches[1];
1766 // FIXME use direct rendering
1767 av_image_copy(data, linesize, (const uint8_t **)src_frame->data, src_frame->linesize,
1768 src_frame->format, vp->width, vp->height);
1771 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1773 const AVClass *class = sws_get_class();
1774 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1775 AV_OPT_SEARCH_FAKE_OBJ);
1776 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1782 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1783 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1784 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1785 if (!is->img_convert_ctx) {
1786 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1789 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1790 0, vp->height, data, linesize);
1792 /* workaround SDL PITCH_WORKAROUND */
1793 duplicate_right_border_pixels(vp->bmp);
1794 /* update the bitmap content */
1795 SDL_UnlockYUVOverlay(vp->bmp);
1798 vp->duration = duration;
1800 vp->serial = serial;
1802 /* now we can update the picture count */
1803 frame_queue_push(&is->pictq);
1808 static int get_video_frame(VideoState *is, AVFrame *frame)
1812 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1818 if (frame->pts != AV_NOPTS_VALUE)
1819 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1821 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1823 is->viddec_width = frame->width;
1824 is->viddec_height = frame->height;
1826 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1827 if (frame->pts != AV_NOPTS_VALUE) {
1828 double diff = dpts - get_master_clock(is);
1829 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1830 diff - is->frame_last_filter_delay < 0 &&
1831 is->viddec.pkt_serial == is->vidclk.serial &&
1832 is->videoq.nb_packets) {
1833 is->frame_drops_early++;
1834 av_frame_unref(frame);
1845 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1846 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1849 int nb_filters = graph->nb_filters;
1850 AVFilterInOut *outputs = NULL, *inputs = NULL;
1853 outputs = avfilter_inout_alloc();
1854 inputs = avfilter_inout_alloc();
1855 if (!outputs || !inputs) {
1856 ret = AVERROR(ENOMEM);
1860 outputs->name = av_strdup("in");
1861 outputs->filter_ctx = source_ctx;
1862 outputs->pad_idx = 0;
1863 outputs->next = NULL;
1865 inputs->name = av_strdup("out");
1866 inputs->filter_ctx = sink_ctx;
1867 inputs->pad_idx = 0;
1868 inputs->next = NULL;
1870 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1873 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1877 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1878 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1879 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1881 ret = avfilter_graph_config(graph, NULL);
1883 avfilter_inout_free(&outputs);
1884 avfilter_inout_free(&inputs);
1888 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1890 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1891 char sws_flags_str[512] = "";
1892 char buffersrc_args[256];
1894 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1895 AVCodecParameters *codecpar = is->video_st->codecpar;
1896 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1897 AVDictionaryEntry *e = NULL;
1899 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1900 if (!strcmp(e->key, "sws_flags")) {
1901 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1903 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1905 if (strlen(sws_flags_str))
1906 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1908 graph->scale_sws_opts = av_strdup(sws_flags_str);
1910 snprintf(buffersrc_args, sizeof(buffersrc_args),
1911 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1912 frame->width, frame->height, frame->format,
1913 is->video_st->time_base.num, is->video_st->time_base.den,
1914 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1915 if (fr.num && fr.den)
1916 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1918 if ((ret = avfilter_graph_create_filter(&filt_src,
1919 avfilter_get_by_name("buffer"),
1920 "ffplay_buffer", buffersrc_args, NULL,
1924 ret = avfilter_graph_create_filter(&filt_out,
1925 avfilter_get_by_name("buffersink"),
1926 "ffplay_buffersink", NULL, NULL, graph);
1930 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1933 last_filter = filt_out;
1935 /* Note: this macro adds a filter before the lastly added filter, so the
1936 * processing order of the filters is in reverse */
1937 #define INSERT_FILT(name, arg) do { \
1938 AVFilterContext *filt_ctx; \
1940 ret = avfilter_graph_create_filter(&filt_ctx, \
1941 avfilter_get_by_name(name), \
1942 "ffplay_" name, arg, NULL, graph); \
1946 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1950 last_filter = filt_ctx; \
1953 /* SDL YUV code is not handling odd width/height for some driver
1954 * combinations, therefore we crop the picture to an even width/height. */
1955 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1958 double theta = get_rotation(is->video_st);
1960 if (fabs(theta - 90) < 1.0) {
1961 INSERT_FILT("transpose", "clock");
1962 } else if (fabs(theta - 180) < 1.0) {
1963 INSERT_FILT("hflip", NULL);
1964 INSERT_FILT("vflip", NULL);
1965 } else if (fabs(theta - 270) < 1.0) {
1966 INSERT_FILT("transpose", "cclock");
1967 } else if (fabs(theta) > 1.0) {
1968 char rotate_buf[64];
1969 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1970 INSERT_FILT("rotate", rotate_buf);
1974 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1977 is->in_video_filter = filt_src;
1978 is->out_video_filter = filt_out;
1984 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1986 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1987 int sample_rates[2] = { 0, -1 };
1988 int64_t channel_layouts[2] = { 0, -1 };
1989 int channels[2] = { 0, -1 };
1990 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1991 char aresample_swr_opts[512] = "";
1992 AVDictionaryEntry *e = NULL;
1993 char asrc_args[256];
1996 avfilter_graph_free(&is->agraph);
1997 if (!(is->agraph = avfilter_graph_alloc()))
1998 return AVERROR(ENOMEM);
2000 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2001 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2002 if (strlen(aresample_swr_opts))
2003 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2004 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2006 ret = snprintf(asrc_args, sizeof(asrc_args),
2007 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2008 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2009 is->audio_filter_src.channels,
2010 1, is->audio_filter_src.freq);
2011 if (is->audio_filter_src.channel_layout)
2012 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2013 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2015 ret = avfilter_graph_create_filter(&filt_asrc,
2016 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2017 asrc_args, NULL, is->agraph);
2022 ret = avfilter_graph_create_filter(&filt_asink,
2023 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2024 NULL, NULL, is->agraph);
2028 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2030 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2033 if (force_output_format) {
2034 channel_layouts[0] = is->audio_tgt.channel_layout;
2035 channels [0] = is->audio_tgt.channels;
2036 sample_rates [0] = is->audio_tgt.freq;
2037 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2039 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2041 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2043 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2048 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2051 is->in_audio_filter = filt_asrc;
2052 is->out_audio_filter = filt_asink;
2056 avfilter_graph_free(&is->agraph);
2059 #endif /* CONFIG_AVFILTER */
2061 static int audio_thread(void *arg)
2063 VideoState *is = arg;
2064 AVFrame *frame = av_frame_alloc();
2067 int last_serial = -1;
2068 int64_t dec_channel_layout;
2076 return AVERROR(ENOMEM);
2079 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2083 tb = (AVRational){1, frame->sample_rate};
2086 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2089 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2090 frame->format, av_frame_get_channels(frame)) ||
2091 is->audio_filter_src.channel_layout != dec_channel_layout ||
2092 is->audio_filter_src.freq != frame->sample_rate ||
2093 is->auddec.pkt_serial != last_serial;
2096 char buf1[1024], buf2[1024];
2097 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2098 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2099 av_log(NULL, AV_LOG_DEBUG,
2100 "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",
2101 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2102 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2104 is->audio_filter_src.fmt = frame->format;
2105 is->audio_filter_src.channels = av_frame_get_channels(frame);
2106 is->audio_filter_src.channel_layout = dec_channel_layout;
2107 is->audio_filter_src.freq = frame->sample_rate;
2108 last_serial = is->auddec.pkt_serial;
2110 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2114 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2117 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2118 tb = is->out_audio_filter->inputs[0]->time_base;
2120 if (!(af = frame_queue_peek_writable(&is->sampq)))
2123 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2124 af->pos = av_frame_get_pkt_pos(frame);
2125 af->serial = is->auddec.pkt_serial;
2126 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2128 av_frame_move_ref(af->frame, frame);
2129 frame_queue_push(&is->sampq);
2132 if (is->audioq.serial != is->auddec.pkt_serial)
2135 if (ret == AVERROR_EOF)
2136 is->auddec.finished = is->auddec.pkt_serial;
2139 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2142 avfilter_graph_free(&is->agraph);
2144 av_frame_free(&frame);
2148 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2150 packet_queue_start(d->queue);
2151 d->decoder_tid = SDL_CreateThread(fn, arg);
2152 if (!d->decoder_tid) {
2153 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2154 return AVERROR(ENOMEM);
2159 static int video_thread(void *arg)
2161 VideoState *is = arg;
2162 AVFrame *frame = av_frame_alloc();
2166 AVRational tb = is->video_st->time_base;
2167 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2170 AVFilterGraph *graph = avfilter_graph_alloc();
2171 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2174 enum AVPixelFormat last_format = -2;
2175 int last_serial = -1;
2176 int last_vfilter_idx = 0;
2178 av_frame_free(&frame);
2179 return AVERROR(ENOMEM);
2186 avfilter_graph_free(&graph);
2188 return AVERROR(ENOMEM);
2192 ret = get_video_frame(is, frame);
2199 if ( last_w != frame->width
2200 || last_h != frame->height
2201 || last_format != frame->format
2202 || last_serial != is->viddec.pkt_serial
2203 || last_vfilter_idx != is->vfilter_idx) {
2204 av_log(NULL, AV_LOG_DEBUG,
2205 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2207 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2208 frame->width, frame->height,
2209 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2210 avfilter_graph_free(&graph);
2211 graph = avfilter_graph_alloc();
2212 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2214 event.type = FF_QUIT_EVENT;
2215 event.user.data1 = is;
2216 SDL_PushEvent(&event);
2219 filt_in = is->in_video_filter;
2220 filt_out = is->out_video_filter;
2221 last_w = frame->width;
2222 last_h = frame->height;
2223 last_format = frame->format;
2224 last_serial = is->viddec.pkt_serial;
2225 last_vfilter_idx = is->vfilter_idx;
2226 frame_rate = filt_out->inputs[0]->frame_rate;
2229 ret = av_buffersrc_add_frame(filt_in, frame);
2234 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2236 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2238 if (ret == AVERROR_EOF)
2239 is->viddec.finished = is->viddec.pkt_serial;
2244 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2245 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2246 is->frame_last_filter_delay = 0;
2247 tb = filt_out->inputs[0]->time_base;
2249 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2250 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2251 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2252 av_frame_unref(frame);
2262 avfilter_graph_free(&graph);
2264 av_frame_free(&frame);
2268 static int subtitle_thread(void *arg)
2270 VideoState *is = arg;
2277 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2280 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2285 if (got_subtitle && sp->sub.format == 0) {
2286 if (sp->sub.pts != AV_NOPTS_VALUE)
2287 pts = sp->sub.pts / (double)AV_TIME_BASE;
2289 sp->serial = is->subdec.pkt_serial;
2290 if (!(sp->subrects = av_mallocz_array(sp->sub.num_rects, sizeof(AVSubtitleRect*)))) {
2291 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subrects\n");
2295 for (i = 0; i < sp->sub.num_rects; i++)
2297 int in_w = sp->sub.rects[i]->w;
2298 int in_h = sp->sub.rects[i]->h;
2299 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2300 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2301 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2302 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2304 if (!(sp->subrects[i] = av_mallocz(sizeof(AVSubtitleRect))) ||
2305 av_image_alloc(sp->subrects[i]->data, sp->subrects[i]->linesize, out_w, out_h, AV_PIX_FMT_YUVA420P, 16) < 0) {
2306 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subtitle data\n");
2310 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2311 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2312 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2313 if (!is->sub_convert_ctx) {
2314 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2317 sws_scale(is->sub_convert_ctx,
2318 (void*)sp->sub.rects[i]->data, sp->sub.rects[i]->linesize,
2319 0, in_h, sp->subrects[i]->data, sp->subrects[i]->linesize);
2321 sp->subrects[i]->w = out_w;
2322 sp->subrects[i]->h = out_h;
2323 sp->subrects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2324 sp->subrects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2327 /* now we can update the picture count */
2328 frame_queue_push(&is->subpq);
2329 } else if (got_subtitle) {
2330 avsubtitle_free(&sp->sub);
2336 /* copy samples for viewing in editor window */
2337 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2341 size = samples_size / sizeof(short);
2343 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2346 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2348 is->sample_array_index += len;
2349 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2350 is->sample_array_index = 0;
2355 /* return the wanted number of samples to get better sync if sync_type is video
2356 * or external master clock */
2357 static int synchronize_audio(VideoState *is, int nb_samples)
2359 int wanted_nb_samples = nb_samples;
2361 /* if not master, then we try to remove or add samples to correct the clock */
2362 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2363 double diff, avg_diff;
2364 int min_nb_samples, max_nb_samples;
2366 diff = get_clock(&is->audclk) - get_master_clock(is);
2368 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2369 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2370 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2371 /* not enough measures to have a correct estimate */
2372 is->audio_diff_avg_count++;
2374 /* estimate the A-V difference */
2375 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2377 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2378 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2379 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2380 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2381 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2383 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2384 diff, avg_diff, wanted_nb_samples - nb_samples,
2385 is->audio_clock, is->audio_diff_threshold);
2388 /* too big difference : may be initial PTS errors, so
2390 is->audio_diff_avg_count = 0;
2391 is->audio_diff_cum = 0;
2395 return wanted_nb_samples;
2399 * Decode one audio frame and return its uncompressed size.
2401 * The processed audio frame is decoded, converted if required, and
2402 * stored in is->audio_buf, with size in bytes given by the return
2405 static int audio_decode_frame(VideoState *is)
2407 int data_size, resampled_data_size;
2408 int64_t dec_channel_layout;
2409 av_unused double audio_clock0;
2410 int wanted_nb_samples;
2418 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2419 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2424 if (!(af = frame_queue_peek_readable(&is->sampq)))
2426 frame_queue_next(&is->sampq);
2427 } while (af->serial != is->audioq.serial);
2429 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2430 af->frame->nb_samples,
2431 af->frame->format, 1);
2433 dec_channel_layout =
2434 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2435 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2436 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2438 if (af->frame->format != is->audio_src.fmt ||
2439 dec_channel_layout != is->audio_src.channel_layout ||
2440 af->frame->sample_rate != is->audio_src.freq ||
2441 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2442 swr_free(&is->swr_ctx);
2443 is->swr_ctx = swr_alloc_set_opts(NULL,
2444 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2445 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2447 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2448 av_log(NULL, AV_LOG_ERROR,
2449 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2450 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2451 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2452 swr_free(&is->swr_ctx);
2455 is->audio_src.channel_layout = dec_channel_layout;
2456 is->audio_src.channels = av_frame_get_channels(af->frame);
2457 is->audio_src.freq = af->frame->sample_rate;
2458 is->audio_src.fmt = af->frame->format;
2462 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2463 uint8_t **out = &is->audio_buf1;
2464 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2465 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2468 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2471 if (wanted_nb_samples != af->frame->nb_samples) {
2472 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2473 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2474 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2478 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2479 if (!is->audio_buf1)
2480 return AVERROR(ENOMEM);
2481 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2483 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2486 if (len2 == out_count) {
2487 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2488 if (swr_init(is->swr_ctx) < 0)
2489 swr_free(&is->swr_ctx);
2491 is->audio_buf = is->audio_buf1;
2492 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2494 is->audio_buf = af->frame->data[0];
2495 resampled_data_size = data_size;
2498 audio_clock0 = is->audio_clock;
2499 /* update the audio clock with the pts */
2500 if (!isnan(af->pts))
2501 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2503 is->audio_clock = NAN;
2504 is->audio_clock_serial = af->serial;
2507 static double last_clock;
2508 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2509 is->audio_clock - last_clock,
2510 is->audio_clock, audio_clock0);
2511 last_clock = is->audio_clock;
2514 return resampled_data_size;
2517 /* prepare a new audio buffer */
2518 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2520 VideoState *is = opaque;
2521 int audio_size, len1;
2523 audio_callback_time = av_gettime_relative();
2526 if (is->audio_buf_index >= is->audio_buf_size) {
2527 audio_size = audio_decode_frame(is);
2528 if (audio_size < 0) {
2529 /* if error, just output silence */
2530 is->audio_buf = NULL;
2531 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2533 if (is->show_mode != SHOW_MODE_VIDEO)
2534 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2535 is->audio_buf_size = audio_size;
2537 is->audio_buf_index = 0;
2539 len1 = is->audio_buf_size - is->audio_buf_index;
2542 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2543 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2545 memset(stream, 0, len1);
2546 if (!is->muted && is->audio_buf)
2547 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2551 is->audio_buf_index += len1;
2553 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2554 /* Let's assume the audio driver that is used by SDL has two periods. */
2555 if (!isnan(is->audio_clock)) {
2556 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);
2557 sync_clock_to_slave(&is->extclk, &is->audclk);
2561 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2563 SDL_AudioSpec wanted_spec, spec;
2565 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2566 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2567 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2569 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2571 wanted_nb_channels = atoi(env);
2572 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2574 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2575 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2576 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2578 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2579 wanted_spec.channels = wanted_nb_channels;
2580 wanted_spec.freq = wanted_sample_rate;
2581 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2582 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2585 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2586 next_sample_rate_idx--;
2587 wanted_spec.format = AUDIO_S16SYS;
2588 wanted_spec.silence = 0;
2589 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2590 wanted_spec.callback = sdl_audio_callback;
2591 wanted_spec.userdata = opaque;
2592 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2593 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2594 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2595 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2596 if (!wanted_spec.channels) {
2597 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2598 wanted_spec.channels = wanted_nb_channels;
2599 if (!wanted_spec.freq) {
2600 av_log(NULL, AV_LOG_ERROR,
2601 "No more combinations to try, audio open failed\n");
2605 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2607 if (spec.format != AUDIO_S16SYS) {
2608 av_log(NULL, AV_LOG_ERROR,
2609 "SDL advised audio format %d is not supported!\n", spec.format);
2612 if (spec.channels != wanted_spec.channels) {
2613 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2614 if (!wanted_channel_layout) {
2615 av_log(NULL, AV_LOG_ERROR,
2616 "SDL advised channel count %d is not supported!\n", spec.channels);
2621 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2622 audio_hw_params->freq = spec.freq;
2623 audio_hw_params->channel_layout = wanted_channel_layout;
2624 audio_hw_params->channels = spec.channels;
2625 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2626 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);
2627 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2628 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2634 /* open a given stream. Return 0 if OK */
2635 static int stream_component_open(VideoState *is, int stream_index)
2637 AVFormatContext *ic = is->ic;
2638 AVCodecContext *avctx;
2640 const char *forced_codec_name = NULL;
2641 AVDictionary *opts = NULL;
2642 AVDictionaryEntry *t = NULL;
2643 int sample_rate, nb_channels;
2644 int64_t channel_layout;
2646 int stream_lowres = lowres;
2648 if (stream_index < 0 || stream_index >= ic->nb_streams)
2651 avctx = avcodec_alloc_context3(NULL);
2653 return AVERROR(ENOMEM);
2655 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2658 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2660 codec = avcodec_find_decoder(avctx->codec_id);
2662 switch(avctx->codec_type){
2663 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2664 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2665 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2667 if (forced_codec_name)
2668 codec = avcodec_find_decoder_by_name(forced_codec_name);
2670 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2671 "No codec could be found with name '%s'\n", forced_codec_name);
2672 else av_log(NULL, AV_LOG_WARNING,
2673 "No codec could be found with id %d\n", avctx->codec_id);
2674 ret = AVERROR(EINVAL);
2678 avctx->codec_id = codec->id;
2679 if(stream_lowres > av_codec_get_max_lowres(codec)){
2680 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2681 av_codec_get_max_lowres(codec));
2682 stream_lowres = av_codec_get_max_lowres(codec);
2684 av_codec_set_lowres(avctx, stream_lowres);
2687 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2690 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2692 if(codec->capabilities & AV_CODEC_CAP_DR1)
2693 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2696 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2697 if (!av_dict_get(opts, "threads", NULL, 0))
2698 av_dict_set(&opts, "threads", "auto", 0);
2700 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2701 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2702 av_dict_set(&opts, "refcounted_frames", "1", 0);
2703 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2706 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2707 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2708 ret = AVERROR_OPTION_NOT_FOUND;
2713 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2714 switch (avctx->codec_type) {
2715 case AVMEDIA_TYPE_AUDIO:
2720 is->audio_filter_src.freq = avctx->sample_rate;
2721 is->audio_filter_src.channels = avctx->channels;
2722 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2723 is->audio_filter_src.fmt = avctx->sample_fmt;
2724 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2726 link = is->out_audio_filter->inputs[0];
2727 sample_rate = link->sample_rate;
2728 nb_channels = avfilter_link_get_channels(link);
2729 channel_layout = link->channel_layout;
2732 sample_rate = avctx->sample_rate;
2733 nb_channels = avctx->channels;
2734 channel_layout = avctx->channel_layout;
2737 /* prepare audio output */
2738 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2740 is->audio_hw_buf_size = ret;
2741 is->audio_src = is->audio_tgt;
2742 is->audio_buf_size = 0;
2743 is->audio_buf_index = 0;
2745 /* init averaging filter */
2746 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2747 is->audio_diff_avg_count = 0;
2748 /* since we do not have a precise anough audio FIFO fullness,
2749 we correct audio sync only if larger than this threshold */
2750 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2752 is->audio_stream = stream_index;
2753 is->audio_st = ic->streams[stream_index];
2755 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2756 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2757 is->auddec.start_pts = is->audio_st->start_time;
2758 is->auddec.start_pts_tb = is->audio_st->time_base;
2760 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2764 case AVMEDIA_TYPE_VIDEO:
2765 is->video_stream = stream_index;
2766 is->video_st = ic->streams[stream_index];
2768 is->viddec_width = avctx->width;
2769 is->viddec_height = avctx->height;
2771 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2772 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2774 is->queue_attachments_req = 1;
2776 case AVMEDIA_TYPE_SUBTITLE:
2777 is->subtitle_stream = stream_index;
2778 is->subtitle_st = ic->streams[stream_index];
2780 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2781 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2790 avcodec_free_context(&avctx);
2792 av_dict_free(&opts);
2797 static int decode_interrupt_cb(void *ctx)
2799 VideoState *is = ctx;
2800 return is->abort_request;
2803 static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2804 return stream_id < 0 ||
2805 queue->abort_request ||
2806 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2807 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2810 static int is_realtime(AVFormatContext *s)
2812 if( !strcmp(s->iformat->name, "rtp")
2813 || !strcmp(s->iformat->name, "rtsp")
2814 || !strcmp(s->iformat->name, "sdp")
2818 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2819 || !strncmp(s->filename, "udp:", 4)
2826 /* this thread gets the stream from the disk or the network */
2827 static int read_thread(void *arg)
2829 VideoState *is = arg;
2830 AVFormatContext *ic = NULL;
2832 int st_index[AVMEDIA_TYPE_NB];
2833 AVPacket pkt1, *pkt = &pkt1;
2834 int64_t stream_start_time;
2835 int pkt_in_play_range = 0;
2836 AVDictionaryEntry *t;
2837 AVDictionary **opts;
2838 int orig_nb_streams;
2839 SDL_mutex *wait_mutex = SDL_CreateMutex();
2840 int scan_all_pmts_set = 0;
2844 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2845 ret = AVERROR(ENOMEM);
2849 memset(st_index, -1, sizeof(st_index));
2850 is->last_video_stream = is->video_stream = -1;
2851 is->last_audio_stream = is->audio_stream = -1;
2852 is->last_subtitle_stream = is->subtitle_stream = -1;
2855 ic = avformat_alloc_context();
2857 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2858 ret = AVERROR(ENOMEM);
2861 ic->interrupt_callback.callback = decode_interrupt_cb;
2862 ic->interrupt_callback.opaque = is;
2863 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2864 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2865 scan_all_pmts_set = 1;
2867 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2869 print_error(is->filename, err);
2873 if (scan_all_pmts_set)
2874 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2876 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2877 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2878 ret = AVERROR_OPTION_NOT_FOUND;
2884 ic->flags |= AVFMT_FLAG_GENPTS;
2886 av_format_inject_global_side_data(ic);
2888 opts = setup_find_stream_info_opts(ic, codec_opts);
2889 orig_nb_streams = ic->nb_streams;
2891 err = avformat_find_stream_info(ic, opts);
2893 for (i = 0; i < orig_nb_streams; i++)
2894 av_dict_free(&opts[i]);
2898 av_log(NULL, AV_LOG_WARNING,
2899 "%s: could not find codec parameters\n", is->filename);
2905 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2907 if (seek_by_bytes < 0)
2908 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2910 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2912 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2913 window_title = av_asprintf("%s - %s", t->value, input_filename);
2915 /* if seeking requested, we execute it */
2916 if (start_time != AV_NOPTS_VALUE) {
2919 timestamp = start_time;
2920 /* add the stream start time */
2921 if (ic->start_time != AV_NOPTS_VALUE)
2922 timestamp += ic->start_time;
2923 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2925 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2926 is->filename, (double)timestamp / AV_TIME_BASE);
2930 is->realtime = is_realtime(ic);
2933 av_dump_format(ic, 0, is->filename, 0);
2935 for (i = 0; i < ic->nb_streams; i++) {
2936 AVStream *st = ic->streams[i];
2937 enum AVMediaType type = st->codecpar->codec_type;
2938 st->discard = AVDISCARD_ALL;
2939 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2940 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2943 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2944 if (wanted_stream_spec[i] && st_index[i] == -1) {
2945 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));
2946 st_index[i] = INT_MAX;
2951 st_index[AVMEDIA_TYPE_VIDEO] =
2952 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2953 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2955 st_index[AVMEDIA_TYPE_AUDIO] =
2956 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2957 st_index[AVMEDIA_TYPE_AUDIO],
2958 st_index[AVMEDIA_TYPE_VIDEO],
2960 if (!video_disable && !subtitle_disable)
2961 st_index[AVMEDIA_TYPE_SUBTITLE] =
2962 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2963 st_index[AVMEDIA_TYPE_SUBTITLE],
2964 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2965 st_index[AVMEDIA_TYPE_AUDIO] :
2966 st_index[AVMEDIA_TYPE_VIDEO]),
2969 is->show_mode = show_mode;
2970 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2971 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2972 AVCodecParameters *codecpar = st->codecpar;
2973 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2974 if (codecpar->width)
2975 set_default_window_size(codecpar->width, codecpar->height, sar);
2978 /* open the streams */
2979 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2980 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2984 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2985 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2987 if (is->show_mode == SHOW_MODE_NONE)
2988 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2990 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2991 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2994 if (is->video_stream < 0 && is->audio_stream < 0) {
2995 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
3001 if (infinite_buffer < 0 && is->realtime)
3002 infinite_buffer = 1;
3005 if (is->abort_request)
3007 if (is->paused != is->last_paused) {
3008 is->last_paused = is->paused;
3010 is->read_pause_return = av_read_pause(ic);
3014 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3016 (!strcmp(ic->iformat->name, "rtsp") ||
3017 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3018 /* wait 10 ms to avoid trying to get another packet */
3025 int64_t seek_target = is->seek_pos;
3026 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3027 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3028 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3029 // of the seek_pos/seek_rel variables
3031 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3033 av_log(NULL, AV_LOG_ERROR,
3034 "%s: error while seeking\n", is->ic->filename);
3036 if (is->audio_stream >= 0) {
3037 packet_queue_flush(&is->audioq);
3038 packet_queue_put(&is->audioq, &flush_pkt);
3040 if (is->subtitle_stream >= 0) {
3041 packet_queue_flush(&is->subtitleq);
3042 packet_queue_put(&is->subtitleq, &flush_pkt);
3044 if (is->video_stream >= 0) {
3045 packet_queue_flush(&is->videoq);
3046 packet_queue_put(&is->videoq, &flush_pkt);
3048 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3049 set_clock(&is->extclk, NAN, 0);
3051 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3055 is->queue_attachments_req = 1;
3058 step_to_next_frame(is);
3060 if (is->queue_attachments_req) {
3061 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3063 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3065 packet_queue_put(&is->videoq, ©);
3066 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3068 is->queue_attachments_req = 0;
3071 /* if the queue are full, no need to read more */
3072 if (infinite_buffer<1 &&
3073 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3074 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
3075 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
3076 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
3078 SDL_LockMutex(wait_mutex);
3079 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3080 SDL_UnlockMutex(wait_mutex);
3084 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3085 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3086 if (loop != 1 && (!loop || --loop)) {
3087 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3088 } else if (autoexit) {
3093 ret = av_read_frame(ic, pkt);
3095 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3096 if (is->video_stream >= 0)
3097 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3098 if (is->audio_stream >= 0)
3099 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3100 if (is->subtitle_stream >= 0)
3101 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3104 if (ic->pb && ic->pb->error)
3106 SDL_LockMutex(wait_mutex);
3107 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3108 SDL_UnlockMutex(wait_mutex);
3113 /* check if packet is in play range specified by user, then queue, otherwise discard */
3114 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3115 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3116 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3117 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3118 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3119 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3120 <= ((double)duration / 1000000);
3121 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3122 packet_queue_put(&is->audioq, pkt);
3123 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3124 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3125 packet_queue_put(&is->videoq, pkt);
3126 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3127 packet_queue_put(&is->subtitleq, pkt);
3129 av_packet_unref(pkt);
3136 avformat_close_input(&ic);
3141 event.type = FF_QUIT_EVENT;
3142 event.user.data1 = is;
3143 SDL_PushEvent(&event);
3145 SDL_DestroyMutex(wait_mutex);
3149 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3153 is = av_mallocz(sizeof(VideoState));
3156 is->filename = av_strdup(filename);
3159 is->iformat = iformat;
3163 /* start video display */
3164 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3166 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3168 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3171 if (packet_queue_init(&is->videoq) < 0 ||
3172 packet_queue_init(&is->audioq) < 0 ||
3173 packet_queue_init(&is->subtitleq) < 0)
3176 if (!(is->continue_read_thread = SDL_CreateCond())) {
3177 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3181 init_clock(&is->vidclk, &is->videoq.serial);
3182 init_clock(&is->audclk, &is->audioq.serial);
3183 init_clock(&is->extclk, &is->extclk.serial);
3184 is->audio_clock_serial = -1;
3185 is->audio_volume = SDL_MIX_MAXVOLUME;
3187 is->av_sync_type = av_sync_type;
3188 is->read_tid = SDL_CreateThread(read_thread, is);
3189 if (!is->read_tid) {
3190 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3198 static void stream_cycle_channel(VideoState *is, int codec_type)
3200 AVFormatContext *ic = is->ic;
3201 int start_index, stream_index;
3204 AVProgram *p = NULL;
3205 int nb_streams = is->ic->nb_streams;
3207 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3208 start_index = is->last_video_stream;
3209 old_index = is->video_stream;
3210 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3211 start_index = is->last_audio_stream;
3212 old_index = is->audio_stream;
3214 start_index = is->last_subtitle_stream;
3215 old_index = is->subtitle_stream;
3217 stream_index = start_index;
3219 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3220 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3222 nb_streams = p->nb_stream_indexes;
3223 for (start_index = 0; start_index < nb_streams; start_index++)
3224 if (p->stream_index[start_index] == stream_index)
3226 if (start_index == nb_streams)
3228 stream_index = start_index;
3233 if (++stream_index >= nb_streams)
3235 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3238 is->last_subtitle_stream = -1;
3241 if (start_index == -1)
3245 if (stream_index == start_index)
3247 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3248 if (st->codecpar->codec_type == codec_type) {
3249 /* check that parameters are OK */
3250 switch (codec_type) {
3251 case AVMEDIA_TYPE_AUDIO:
3252 if (st->codecpar->sample_rate != 0 &&
3253 st->codecpar->channels != 0)
3256 case AVMEDIA_TYPE_VIDEO:
3257 case AVMEDIA_TYPE_SUBTITLE:
3265 if (p && stream_index != -1)
3266 stream_index = p->stream_index[stream_index];
3267 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3268 av_get_media_type_string(codec_type),
3272 stream_component_close(is, old_index);
3273 stream_component_open(is, stream_index);
3277 static void toggle_full_screen(VideoState *is)
3279 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3280 /* OS X needs to reallocate the SDL overlays */
3282 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3283 is->pictq.queue[i].reallocate = 1;
3285 is_full_screen = !is_full_screen;
3286 video_open(is, 1, NULL);
3289 static void toggle_audio_display(VideoState *is)
3291 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3292 int next = is->show_mode;
3294 next = (next + 1) % SHOW_MODE_NB;
3295 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3296 if (is->show_mode != next) {
3297 fill_rectangle(screen,
3298 is->xleft, is->ytop, is->width, is->height,
3300 is->force_refresh = 1;
3301 is->show_mode = next;
3305 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3306 double remaining_time = 0.0;
3308 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3309 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3313 if (remaining_time > 0.0)
3314 av_usleep((int64_t)(remaining_time * 1000000.0));
3315 remaining_time = REFRESH_RATE;
3316 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3317 video_refresh(is, &remaining_time);
3322 static void seek_chapter(VideoState *is, int incr)
3324 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3327 if (!is->ic->nb_chapters)
3330 /* find the current chapter */
3331 for (i = 0; i < is->ic->nb_chapters; i++) {
3332 AVChapter *ch = is->ic->chapters[i];
3333 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3341 if (i >= is->ic->nb_chapters)
3344 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3345 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3346 AV_TIME_BASE_Q), 0, 0);
3349 /* handle an event sent by the GUI */
3350 static void event_loop(VideoState *cur_stream)
3353 double incr, pos, frac;
3357 refresh_loop_wait_event(cur_stream, &event);
3358 switch (event.type) {
3360 if (exit_on_keydown) {
3361 do_exit(cur_stream);
3364 switch (event.key.keysym.sym) {
3367 do_exit(cur_stream);
3370 toggle_full_screen(cur_stream);
3371 cur_stream->force_refresh = 1;
3375 toggle_pause(cur_stream);
3378 toggle_mute(cur_stream);
3380 case SDLK_KP_MULTIPLY:
3382 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3384 case SDLK_KP_DIVIDE:
3386 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3388 case SDLK_s: // S: Step to next frame
3389 step_to_next_frame(cur_stream);
3392 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3395 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3398 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3399 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3400 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3403 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3407 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3408 if (++cur_stream->vfilter_idx >= nb_vfilters)
3409 cur_stream->vfilter_idx = 0;
3411 cur_stream->vfilter_idx = 0;
3412 toggle_audio_display(cur_stream);
3415 toggle_audio_display(cur_stream);
3419 if (cur_stream->ic->nb_chapters <= 1) {
3423 seek_chapter(cur_stream, 1);
3426 if (cur_stream->ic->nb_chapters <= 1) {
3430 seek_chapter(cur_stream, -1);
3444 if (seek_by_bytes) {
3446 if (pos < 0 && cur_stream->video_stream >= 0)
3447 pos = frame_queue_last_pos(&cur_stream->pictq);
3448 if (pos < 0 && cur_stream->audio_stream >= 0)
3449 pos = frame_queue_last_pos(&cur_stream->sampq);
3451 pos = avio_tell(cur_stream->ic->pb);
3452 if (cur_stream->ic->bit_rate)
3453 incr *= cur_stream->ic->bit_rate / 8.0;
3457 stream_seek(cur_stream, pos, incr, 1);
3459 pos = get_master_clock(cur_stream);
3461 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3463 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3464 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3465 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3472 case SDL_VIDEOEXPOSE:
3473 cur_stream->force_refresh = 1;
3475 case SDL_MOUSEBUTTONDOWN:
3476 if (exit_on_mousedown) {
3477 do_exit(cur_stream);
3480 if (event.button.button == SDL_BUTTON_LEFT) {
3481 static int64_t last_mouse_left_click = 0;
3482 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3483 toggle_full_screen(cur_stream);
3484 cur_stream->force_refresh = 1;
3485 last_mouse_left_click = 0;
3487 last_mouse_left_click = av_gettime_relative();
3490 case SDL_MOUSEMOTION:
3491 if (cursor_hidden) {
3495 cursor_last_shown = av_gettime_relative();
3496 if (event.type == SDL_MOUSEBUTTONDOWN) {
3497 if (event.button.button != SDL_BUTTON_RIGHT)
3501 if (!(event.motion.state & SDL_BUTTON_RMASK))
3505 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3506 uint64_t size = avio_size(cur_stream->ic->pb);
3507 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3511 int tns, thh, tmm, tss;
3512 tns = cur_stream->ic->duration / 1000000LL;
3514 tmm = (tns % 3600) / 60;
3516 frac = x / cur_stream->width;
3519 mm = (ns % 3600) / 60;
3521 av_log(NULL, AV_LOG_INFO,
3522 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3523 hh, mm, ss, thh, tmm, tss);
3524 ts = frac * cur_stream->ic->duration;
3525 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3526 ts += cur_stream->ic->start_time;
3527 stream_seek(cur_stream, ts, 0, 0);
3530 case SDL_VIDEORESIZE:
3531 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3532 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3534 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3535 do_exit(cur_stream);
3537 screen_width = cur_stream->width = screen->w;
3538 screen_height = cur_stream->height = screen->h;
3539 cur_stream->force_refresh = 1;
3543 do_exit(cur_stream);
3545 case FF_ALLOC_EVENT:
3546 alloc_picture(event.user.data1);
3554 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3556 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3557 return opt_default(NULL, "video_size", arg);
3560 static int opt_width(void *optctx, const char *opt, const char *arg)
3562 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3566 static int opt_height(void *optctx, const char *opt, const char *arg)
3568 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3572 static int opt_format(void *optctx, const char *opt, const char *arg)
3574 file_iformat = av_find_input_format(arg);
3575 if (!file_iformat) {
3576 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3577 return AVERROR(EINVAL);
3582 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3584 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3585 return opt_default(NULL, "pixel_format", arg);
3588 static int opt_sync(void *optctx, const char *opt, const char *arg)
3590 if (!strcmp(arg, "audio"))
3591 av_sync_type = AV_SYNC_AUDIO_MASTER;
3592 else if (!strcmp(arg, "video"))
3593 av_sync_type = AV_SYNC_VIDEO_MASTER;
3594 else if (!strcmp(arg, "ext"))
3595 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3597 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3603 static int opt_seek(void *optctx, const char *opt, const char *arg)
3605 start_time = parse_time_or_die(opt, arg, 1);
3609 static int opt_duration(void *optctx, const char *opt, const char *arg)
3611 duration = parse_time_or_die(opt, arg, 1);
3615 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3617 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3618 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3619 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3620 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3624 static void opt_input_file(void *optctx, const char *filename)
3626 if (input_filename) {
3627 av_log(NULL, AV_LOG_FATAL,
3628 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3629 filename, input_filename);
3632 if (!strcmp(filename, "-"))
3634 input_filename = filename;
3637 static int opt_codec(void *optctx, const char *opt, const char *arg)
3639 const char *spec = strchr(opt, ':');
3641 av_log(NULL, AV_LOG_ERROR,
3642 "No media specifier was specified in '%s' in option '%s'\n",
3644 return AVERROR(EINVAL);
3648 case 'a' : audio_codec_name = arg; break;
3649 case 's' : subtitle_codec_name = arg; break;
3650 case 'v' : video_codec_name = arg; break;
3652 av_log(NULL, AV_LOG_ERROR,
3653 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3654 return AVERROR(EINVAL);
3661 static const OptionDef options[] = {
3662 #include "cmdutils_common_opts.h"
3663 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3664 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3665 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3666 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3667 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3668 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3669 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3670 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3671 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3672 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3673 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3674 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3675 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3676 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3677 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3678 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3679 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3680 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3681 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3682 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3683 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3684 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3685 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3686 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3687 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3688 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3689 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3690 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3691 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3693 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3694 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3696 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3697 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3698 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3699 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3700 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3701 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3702 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3703 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3704 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3708 static void show_usage(void)
3710 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3711 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3712 av_log(NULL, AV_LOG_INFO, "\n");
3715 void show_help_default(const char *opt, const char *arg)
3717 av_log_set_callback(log_callback_help);
3719 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3720 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3722 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3723 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3724 #if !CONFIG_AVFILTER
3725 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3727 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3729 printf("\nWhile playing:\n"
3731 "f toggle full screen\n"
3734 "9, 0 decrease and increase volume respectively\n"
3735 "/, * decrease and increase volume respectively\n"
3736 "a cycle audio channel in the current program\n"
3737 "v cycle video channel\n"
3738 "t cycle subtitle channel in the current program\n"
3740 "w cycle video filters or show modes\n"
3741 "s activate frame-step mode\n"
3742 "left/right seek backward/forward 10 seconds\n"
3743 "down/up seek backward/forward 1 minute\n"
3744 "page down/page up seek backward/forward 10 minutes\n"
3745 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3746 "left double-click toggle full screen\n"
3750 static int lockmgr(void **mtx, enum AVLockOp op)
3753 case AV_LOCK_CREATE:
3754 *mtx = SDL_CreateMutex();
3756 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3760 case AV_LOCK_OBTAIN:
3761 return !!SDL_LockMutex(*mtx);
3762 case AV_LOCK_RELEASE:
3763 return !!SDL_UnlockMutex(*mtx);
3764 case AV_LOCK_DESTROY:
3765 SDL_DestroyMutex(*mtx);
3771 /* Called from the main */
3772 int main(int argc, char **argv)
3776 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3777 char alsa_bufsize[] = "SDL_AUDIO_ALSA_SET_BUFFER_SIZE=1";
3781 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3782 parse_loglevel(argc, argv, options);
3784 /* register all codecs, demux and protocols */
3786 avdevice_register_all();
3789 avfilter_register_all();
3792 avformat_network_init();
3796 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3797 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3799 show_banner(argc, argv, options);
3801 parse_options(NULL, argc, argv, options, opt_input_file);
3803 if (!input_filename) {
3805 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3806 av_log(NULL, AV_LOG_FATAL,
3807 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3811 if (display_disable) {
3814 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3816 flags &= ~SDL_INIT_AUDIO;
3818 /* Try to work around an occasional ALSA buffer underflow issue when the
3819 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3820 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3821 SDL_putenv(alsa_bufsize);
3823 if (display_disable)
3824 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3825 #if !defined(_WIN32) && !defined(__APPLE__)
3826 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3828 if (SDL_Init (flags)) {
3829 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3830 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3834 if (!display_disable) {
3835 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3836 fs_screen_width = vi->current_w;
3837 fs_screen_height = vi->current_h;
3840 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3841 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3842 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3844 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3846 if (av_lockmgr_register(lockmgr)) {
3847 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3851 av_init_packet(&flush_pkt);
3852 flush_pkt.data = (uint8_t *)&flush_pkt;
3854 is = stream_open(input_filename, file_iformat);
3856 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");