2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 static unsigned sws_flags = SWS_BICUBIC;
110 typedef struct MyAVPacketList {
112 struct MyAVPacketList *next;
116 typedef struct PacketQueue {
117 MyAVPacketList *first_pkt, *last_pkt;
126 #define VIDEO_PICTURE_QUEUE_SIZE 3
127 #define SUBPICTURE_QUEUE_SIZE 16
128 #define SAMPLE_QUEUE_SIZE 9
129 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
131 typedef struct AudioParams {
134 int64_t channel_layout;
135 enum AVSampleFormat fmt;
140 typedef struct Clock {
141 double pts; /* clock base */
142 double pts_drift; /* clock base minus time at which we updated the clock */
145 int serial; /* clock is based on a packet with this serial */
147 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
150 /* Common struct for handling all types of decoded data and allocated render buffers. */
151 typedef struct Frame {
154 AVSubtitleRect **subrects; /* rescaled subtitle rectangles in yuva */
156 double pts; /* presentation timestamp for the frame */
157 double duration; /* estimated duration of the frame */
158 int64_t pos; /* byte position of the frame in the input file */
167 typedef struct FrameQueue {
168 Frame queue[FRAME_QUEUE_SIZE];
181 AV_SYNC_AUDIO_MASTER, /* default choice */
182 AV_SYNC_VIDEO_MASTER,
183 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
186 typedef struct Decoder {
190 AVCodecContext *avctx;
194 SDL_cond *empty_queue_cond;
196 AVRational start_pts_tb;
198 AVRational next_pts_tb;
199 SDL_Thread *decoder_tid;
202 typedef struct VideoState {
203 SDL_Thread *read_tid;
204 AVInputFormat *iformat;
209 int queue_attachments_req;
214 int read_pause_return;
238 int audio_clock_serial;
239 double audio_diff_cum; /* used for AV difference average computation */
240 double audio_diff_avg_coef;
241 double audio_diff_threshold;
242 int audio_diff_avg_count;
245 int audio_hw_buf_size;
248 unsigned int audio_buf_size; /* in bytes */
249 unsigned int audio_buf1_size;
250 int audio_buf_index; /* in bytes */
251 int audio_write_buf_size;
254 struct AudioParams audio_src;
256 struct AudioParams audio_filter_src;
258 struct AudioParams audio_tgt;
259 struct SwrContext *swr_ctx;
260 int frame_drops_early;
261 int frame_drops_late;
264 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
266 int16_t sample_array[SAMPLE_ARRAY_SIZE];
267 int sample_array_index;
271 FFTSample *rdft_data;
273 double last_vis_time;
276 AVStream *subtitle_st;
277 PacketQueue subtitleq;
280 double frame_last_returned_time;
281 double frame_last_filter_delay;
285 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
287 struct SwsContext *img_convert_ctx;
289 struct SwsContext *sub_convert_ctx;
290 SDL_Rect last_display_rect;
294 int width, height, xleft, ytop;
299 AVFilterContext *in_video_filter; // the first filter in the video chain
300 AVFilterContext *out_video_filter; // the last filter in the video chain
301 AVFilterContext *in_audio_filter; // the first filter in the audio chain
302 AVFilterContext *out_audio_filter; // the last filter in the audio chain
303 AVFilterGraph *agraph; // audio filter graph
306 int last_video_stream, last_audio_stream, last_subtitle_stream;
308 SDL_cond *continue_read_thread;
311 /* options specified by the user */
312 static AVInputFormat *file_iformat;
313 static const char *input_filename;
314 static const char *window_title;
315 static int fs_screen_width;
316 static int fs_screen_height;
317 static int default_width = 640;
318 static int default_height = 480;
319 static int screen_width = 0;
320 static int screen_height = 0;
321 static int audio_disable;
322 static int video_disable;
323 static int subtitle_disable;
324 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
325 static int seek_by_bytes = -1;
326 static int display_disable;
327 static int show_status = 1;
328 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
329 static int64_t start_time = AV_NOPTS_VALUE;
330 static int64_t duration = AV_NOPTS_VALUE;
332 static int genpts = 0;
333 static int lowres = 0;
334 static int decoder_reorder_pts = -1;
336 static int exit_on_keydown;
337 static int exit_on_mousedown;
339 static int framedrop = -1;
340 static int infinite_buffer = -1;
341 static enum ShowMode show_mode = SHOW_MODE_NONE;
342 static const char *audio_codec_name;
343 static const char *subtitle_codec_name;
344 static const char *video_codec_name;
345 double rdftspeed = 0.02;
346 static int64_t cursor_last_shown;
347 static int cursor_hidden = 0;
349 static const char **vfilters_list = NULL;
350 static int nb_vfilters = 0;
351 static char *afilters = NULL;
353 static int autorotate = 1;
355 /* current context */
356 static int is_full_screen;
357 static int64_t audio_callback_time;
359 static AVPacket flush_pkt;
361 #define FF_ALLOC_EVENT (SDL_USEREVENT)
362 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
364 static SDL_Surface *screen;
367 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
369 GROW_ARRAY(vfilters_list, nb_vfilters);
370 vfilters_list[nb_vfilters - 1] = arg;
376 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
377 enum AVSampleFormat fmt2, int64_t channel_count2)
379 /* If channel count == 1, planar and non-planar formats are the same */
380 if (channel_count1 == 1 && channel_count2 == 1)
381 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
383 return channel_count1 != channel_count2 || fmt1 != fmt2;
387 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
389 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
390 return channel_layout;
395 static void free_picture(Frame *vp);
397 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
399 MyAVPacketList *pkt1;
401 if (q->abort_request)
404 pkt1 = av_malloc(sizeof(MyAVPacketList));
409 if (pkt == &flush_pkt)
411 pkt1->serial = q->serial;
416 q->last_pkt->next = pkt1;
419 q->size += pkt1->pkt.size + sizeof(*pkt1);
420 /* XXX: should duplicate packet data in DV case */
421 SDL_CondSignal(q->cond);
425 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
429 SDL_LockMutex(q->mutex);
430 ret = packet_queue_put_private(q, pkt);
431 SDL_UnlockMutex(q->mutex);
433 if (pkt != &flush_pkt && ret < 0)
434 av_packet_unref(pkt);
439 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
441 AVPacket pkt1, *pkt = &pkt1;
445 pkt->stream_index = stream_index;
446 return packet_queue_put(q, pkt);
449 /* packet queue handling */
450 static int packet_queue_init(PacketQueue *q)
452 memset(q, 0, sizeof(PacketQueue));
453 q->mutex = SDL_CreateMutex();
455 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
456 return AVERROR(ENOMEM);
458 q->cond = SDL_CreateCond();
460 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
461 return AVERROR(ENOMEM);
463 q->abort_request = 1;
467 static void packet_queue_flush(PacketQueue *q)
469 MyAVPacketList *pkt, *pkt1;
471 SDL_LockMutex(q->mutex);
472 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
474 av_packet_unref(&pkt->pkt);
481 SDL_UnlockMutex(q->mutex);
484 static void packet_queue_destroy(PacketQueue *q)
486 packet_queue_flush(q);
487 SDL_DestroyMutex(q->mutex);
488 SDL_DestroyCond(q->cond);
491 static void packet_queue_abort(PacketQueue *q)
493 SDL_LockMutex(q->mutex);
495 q->abort_request = 1;
497 SDL_CondSignal(q->cond);
499 SDL_UnlockMutex(q->mutex);
502 static void packet_queue_start(PacketQueue *q)
504 SDL_LockMutex(q->mutex);
505 q->abort_request = 0;
506 packet_queue_put_private(q, &flush_pkt);
507 SDL_UnlockMutex(q->mutex);
510 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
511 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
513 MyAVPacketList *pkt1;
516 SDL_LockMutex(q->mutex);
519 if (q->abort_request) {
526 q->first_pkt = pkt1->next;
530 q->size -= pkt1->pkt.size + sizeof(*pkt1);
533 *serial = pkt1->serial;
541 SDL_CondWait(q->cond, q->mutex);
544 SDL_UnlockMutex(q->mutex);
548 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
549 memset(d, 0, sizeof(Decoder));
552 d->empty_queue_cond = empty_queue_cond;
553 d->start_pts = AV_NOPTS_VALUE;
556 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
562 if (d->queue->abort_request)
565 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
568 if (d->queue->nb_packets == 0)
569 SDL_CondSignal(d->empty_queue_cond);
570 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
572 if (pkt.data == flush_pkt.data) {
573 avcodec_flush_buffers(d->avctx);
575 d->next_pts = d->start_pts;
576 d->next_pts_tb = d->start_pts_tb;
578 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
579 av_packet_unref(&d->pkt);
580 d->pkt_temp = d->pkt = pkt;
581 d->packet_pending = 1;
584 switch (d->avctx->codec_type) {
585 case AVMEDIA_TYPE_VIDEO:
586 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
588 if (decoder_reorder_pts == -1) {
589 frame->pts = av_frame_get_best_effort_timestamp(frame);
590 } else if (decoder_reorder_pts) {
591 frame->pts = frame->pkt_pts;
593 frame->pts = frame->pkt_dts;
597 case AVMEDIA_TYPE_AUDIO:
598 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
600 AVRational tb = (AVRational){1, frame->sample_rate};
601 if (frame->pts != AV_NOPTS_VALUE)
602 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
603 else if (frame->pkt_pts != AV_NOPTS_VALUE)
604 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
605 else if (d->next_pts != AV_NOPTS_VALUE)
606 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
607 if (frame->pts != AV_NOPTS_VALUE) {
608 d->next_pts = frame->pts + frame->nb_samples;
613 case AVMEDIA_TYPE_SUBTITLE:
614 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
619 d->packet_pending = 0;
622 d->pkt_temp.pts = AV_NOPTS_VALUE;
623 if (d->pkt_temp.data) {
624 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
625 ret = d->pkt_temp.size;
626 d->pkt_temp.data += ret;
627 d->pkt_temp.size -= ret;
628 if (d->pkt_temp.size <= 0)
629 d->packet_pending = 0;
632 d->packet_pending = 0;
633 d->finished = d->pkt_serial;
637 } while (!got_frame && !d->finished);
642 static void decoder_destroy(Decoder *d) {
643 av_packet_unref(&d->pkt);
644 avcodec_free_context(&d->avctx);
647 static void frame_queue_unref_item(Frame *vp)
650 for (i = 0; i < vp->sub.num_rects; i++) {
651 av_freep(&vp->subrects[i]->data[0]);
652 av_freep(&vp->subrects[i]);
654 av_freep(&vp->subrects);
655 av_frame_unref(vp->frame);
656 avsubtitle_free(&vp->sub);
659 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
662 memset(f, 0, sizeof(FrameQueue));
663 if (!(f->mutex = SDL_CreateMutex())) {
664 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
665 return AVERROR(ENOMEM);
667 if (!(f->cond = SDL_CreateCond())) {
668 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
669 return AVERROR(ENOMEM);
672 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
673 f->keep_last = !!keep_last;
674 for (i = 0; i < f->max_size; i++)
675 if (!(f->queue[i].frame = av_frame_alloc()))
676 return AVERROR(ENOMEM);
680 static void frame_queue_destory(FrameQueue *f)
683 for (i = 0; i < f->max_size; i++) {
684 Frame *vp = &f->queue[i];
685 frame_queue_unref_item(vp);
686 av_frame_free(&vp->frame);
689 SDL_DestroyMutex(f->mutex);
690 SDL_DestroyCond(f->cond);
693 static void frame_queue_signal(FrameQueue *f)
695 SDL_LockMutex(f->mutex);
696 SDL_CondSignal(f->cond);
697 SDL_UnlockMutex(f->mutex);
700 static Frame *frame_queue_peek(FrameQueue *f)
702 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
705 static Frame *frame_queue_peek_next(FrameQueue *f)
707 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
710 static Frame *frame_queue_peek_last(FrameQueue *f)
712 return &f->queue[f->rindex];
715 static Frame *frame_queue_peek_writable(FrameQueue *f)
717 /* wait until we have space to put a new frame */
718 SDL_LockMutex(f->mutex);
719 while (f->size >= f->max_size &&
720 !f->pktq->abort_request) {
721 SDL_CondWait(f->cond, f->mutex);
723 SDL_UnlockMutex(f->mutex);
725 if (f->pktq->abort_request)
728 return &f->queue[f->windex];
731 static Frame *frame_queue_peek_readable(FrameQueue *f)
733 /* wait until we have a readable a new frame */
734 SDL_LockMutex(f->mutex);
735 while (f->size - f->rindex_shown <= 0 &&
736 !f->pktq->abort_request) {
737 SDL_CondWait(f->cond, f->mutex);
739 SDL_UnlockMutex(f->mutex);
741 if (f->pktq->abort_request)
744 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
747 static void frame_queue_push(FrameQueue *f)
749 if (++f->windex == f->max_size)
751 SDL_LockMutex(f->mutex);
753 SDL_CondSignal(f->cond);
754 SDL_UnlockMutex(f->mutex);
757 static void frame_queue_next(FrameQueue *f)
759 if (f->keep_last && !f->rindex_shown) {
763 frame_queue_unref_item(&f->queue[f->rindex]);
764 if (++f->rindex == f->max_size)
766 SDL_LockMutex(f->mutex);
768 SDL_CondSignal(f->cond);
769 SDL_UnlockMutex(f->mutex);
772 /* return the number of undisplayed frames in the queue */
773 static int frame_queue_nb_remaining(FrameQueue *f)
775 return f->size - f->rindex_shown;
778 /* return last shown position */
779 static int64_t frame_queue_last_pos(FrameQueue *f)
781 Frame *fp = &f->queue[f->rindex];
782 if (f->rindex_shown && fp->serial == f->pktq->serial)
788 static void decoder_abort(Decoder *d, FrameQueue *fq)
790 packet_queue_abort(d->queue);
791 frame_queue_signal(fq);
792 SDL_WaitThread(d->decoder_tid, NULL);
793 d->decoder_tid = NULL;
794 packet_queue_flush(d->queue);
797 static inline void fill_rectangle(SDL_Surface *screen,
798 int x, int y, int w, int h, int color, int update)
805 SDL_FillRect(screen, &rect, color);
806 if (update && w > 0 && h > 0)
807 SDL_UpdateRect(screen, x, y, w, h);
810 /* draw only the border of a rectangle */
811 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
815 /* fill the background */
819 w2 = width - (x + w);
825 h2 = height - (y + h);
828 fill_rectangle(screen,
832 fill_rectangle(screen,
833 xleft + width - w2, ytop,
836 fill_rectangle(screen,
840 fill_rectangle(screen,
841 xleft + w1, ytop + height - h2,
846 #define ALPHA_BLEND(a, oldp, newp, s)\
847 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
853 static void blend_subrect(uint8_t **data, int *linesize, const AVSubtitleRect *rect, int imgw, int imgh)
855 int x, y, Y, U, V, A;
856 uint8_t *lum, *cb, *cr;
857 int dstx, dsty, dstw, dsth;
858 const AVSubtitleRect *src = rect;
860 dstw = av_clip(rect->w, 0, imgw);
861 dsth = av_clip(rect->h, 0, imgh);
862 dstx = av_clip(rect->x, 0, imgw - dstw);
863 dsty = av_clip(rect->y, 0, imgh - dsth);
864 lum = data[0] + dstx + dsty * linesize[0];
865 cb = data[1] + dstx/2 + (dsty >> 1) * linesize[1];
866 cr = data[2] + dstx/2 + (dsty >> 1) * linesize[2];
868 for (y = 0; y<dsth; y++) {
869 for (x = 0; x<dstw; x++) {
870 Y = src->data[0][x + y*src->linesize[0]];
871 A = src->data[3][x + y*src->linesize[3]];
872 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
875 lum += linesize[0] - dstw;
878 for (y = 0; y<dsth/2; y++) {
879 for (x = 0; x<dstw/2; x++) {
880 U = src->data[1][x + y*src->linesize[1]];
881 V = src->data[2][x + y*src->linesize[2]];
882 A = src->data[3][2*x + 2*y *src->linesize[3]]
883 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
884 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
885 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
886 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
887 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
891 cb += linesize[1] - dstw/2;
892 cr += linesize[2] - dstw/2;
896 static void free_picture(Frame *vp)
899 SDL_FreeYUVOverlay(vp->bmp);
904 static void calculate_display_rect(SDL_Rect *rect,
905 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
906 int pic_width, int pic_height, AVRational pic_sar)
909 int width, height, x, y;
911 if (pic_sar.num == 0)
914 aspect_ratio = av_q2d(pic_sar);
916 if (aspect_ratio <= 0.0)
918 aspect_ratio *= (float)pic_width / (float)pic_height;
920 /* XXX: we suppose the screen has a 1.0 pixel ratio */
922 width = lrint(height * aspect_ratio) & ~1;
923 if (width > scr_width) {
925 height = lrint(width / aspect_ratio) & ~1;
927 x = (scr_width - width) / 2;
928 y = (scr_height - height) / 2;
929 rect->x = scr_xleft + x;
930 rect->y = scr_ytop + y;
931 rect->w = FFMAX(width, 1);
932 rect->h = FFMAX(height, 1);
935 static void video_image_display(VideoState *is)
942 vp = frame_queue_peek_last(&is->pictq);
944 if (is->subtitle_st) {
945 if (frame_queue_nb_remaining(&is->subpq) > 0) {
946 sp = frame_queue_peek(&is->subpq);
948 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
952 SDL_LockYUVOverlay (vp->bmp);
954 data[0] = vp->bmp->pixels[0];
955 data[1] = vp->bmp->pixels[2];
956 data[2] = vp->bmp->pixels[1];
958 linesize[0] = vp->bmp->pitches[0];
959 linesize[1] = vp->bmp->pitches[2];
960 linesize[2] = vp->bmp->pitches[1];
962 for (i = 0; i < sp->sub.num_rects; i++)
963 blend_subrect(data, linesize, sp->subrects[i],
964 vp->bmp->w, vp->bmp->h);
966 SDL_UnlockYUVOverlay (vp->bmp);
971 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
973 SDL_DisplayYUVOverlay(vp->bmp, &rect);
975 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) {
976 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
977 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
978 is->last_display_rect = rect;
983 static inline int compute_mod(int a, int b)
985 return a < 0 ? a%b + b : a%b;
988 static void video_audio_display(VideoState *s)
990 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
991 int ch, channels, h, h2, bgcolor, fgcolor;
993 int rdft_bits, nb_freq;
995 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
997 nb_freq = 1 << (rdft_bits - 1);
999 /* compute display index : center on currently output samples */
1000 channels = s->audio_tgt.channels;
1001 nb_display_channels = channels;
1003 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1005 delay = s->audio_write_buf_size;
1008 /* to be more precise, we take into account the time spent since
1009 the last buffer computation */
1010 if (audio_callback_time) {
1011 time_diff = av_gettime_relative() - audio_callback_time;
1012 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1015 delay += 2 * data_used;
1016 if (delay < data_used)
1019 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1020 if (s->show_mode == SHOW_MODE_WAVES) {
1022 for (i = 0; i < 1000; i += channels) {
1023 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1024 int a = s->sample_array[idx];
1025 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1026 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1027 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1029 if (h < score && (b ^ c) < 0) {
1036 s->last_i_start = i_start;
1038 i_start = s->last_i_start;
1041 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1042 if (s->show_mode == SHOW_MODE_WAVES) {
1043 fill_rectangle(screen,
1044 s->xleft, s->ytop, s->width, s->height,
1047 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1049 /* total height for one channel */
1050 h = s->height / nb_display_channels;
1051 /* graph height / 2 */
1053 for (ch = 0; ch < nb_display_channels; ch++) {
1055 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1056 for (x = 0; x < s->width; x++) {
1057 y = (s->sample_array[i] * h2) >> 15;
1064 fill_rectangle(screen,
1065 s->xleft + x, ys, 1, y,
1068 if (i >= SAMPLE_ARRAY_SIZE)
1069 i -= SAMPLE_ARRAY_SIZE;
1073 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1075 for (ch = 1; ch < nb_display_channels; ch++) {
1076 y = s->ytop + ch * h;
1077 fill_rectangle(screen,
1078 s->xleft, y, s->width, 1,
1081 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1083 nb_display_channels= FFMIN(nb_display_channels, 2);
1084 if (rdft_bits != s->rdft_bits) {
1085 av_rdft_end(s->rdft);
1086 av_free(s->rdft_data);
1087 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1088 s->rdft_bits = rdft_bits;
1089 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1091 if (!s->rdft || !s->rdft_data){
1092 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1093 s->show_mode = SHOW_MODE_WAVES;
1096 for (ch = 0; ch < nb_display_channels; ch++) {
1097 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1099 for (x = 0; x < 2 * nb_freq; x++) {
1100 double w = (x-nb_freq) * (1.0 / nb_freq);
1101 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1103 if (i >= SAMPLE_ARRAY_SIZE)
1104 i -= SAMPLE_ARRAY_SIZE;
1106 av_rdft_calc(s->rdft, data[ch]);
1108 /* Least efficient way to do this, we should of course
1109 * directly access it but it is more than fast enough. */
1110 for (y = 0; y < s->height; y++) {
1111 double w = 1 / sqrt(nb_freq);
1112 int a = sqrt(w * hypot(data[0][2 * y + 0], data[0][2 * y + 1]));
1113 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1117 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1119 fill_rectangle(screen,
1120 s->xpos, s->height-y, 1, 1,
1124 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1127 if (s->xpos >= s->width)
1132 static void stream_component_close(VideoState *is, int stream_index)
1134 AVFormatContext *ic = is->ic;
1135 AVCodecParameters *codecpar;
1137 if (stream_index < 0 || stream_index >= ic->nb_streams)
1139 codecpar = ic->streams[stream_index]->codecpar;
1141 switch (codecpar->codec_type) {
1142 case AVMEDIA_TYPE_AUDIO:
1143 decoder_abort(&is->auddec, &is->sampq);
1145 decoder_destroy(&is->auddec);
1146 swr_free(&is->swr_ctx);
1147 av_freep(&is->audio_buf1);
1148 is->audio_buf1_size = 0;
1149 is->audio_buf = NULL;
1152 av_rdft_end(is->rdft);
1153 av_freep(&is->rdft_data);
1158 case AVMEDIA_TYPE_VIDEO:
1159 decoder_abort(&is->viddec, &is->pictq);
1160 decoder_destroy(&is->viddec);
1162 case AVMEDIA_TYPE_SUBTITLE:
1163 decoder_abort(&is->subdec, &is->subpq);
1164 decoder_destroy(&is->subdec);
1170 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1171 switch (codecpar->codec_type) {
1172 case AVMEDIA_TYPE_AUDIO:
1173 is->audio_st = NULL;
1174 is->audio_stream = -1;
1176 case AVMEDIA_TYPE_VIDEO:
1177 is->video_st = NULL;
1178 is->video_stream = -1;
1180 case AVMEDIA_TYPE_SUBTITLE:
1181 is->subtitle_st = NULL;
1182 is->subtitle_stream = -1;
1189 static void stream_close(VideoState *is)
1191 /* XXX: use a special url_shutdown call to abort parse cleanly */
1192 is->abort_request = 1;
1193 SDL_WaitThread(is->read_tid, NULL);
1195 /* close each stream */
1196 if (is->audio_stream >= 0)
1197 stream_component_close(is, is->audio_stream);
1198 if (is->video_stream >= 0)
1199 stream_component_close(is, is->video_stream);
1200 if (is->subtitle_stream >= 0)
1201 stream_component_close(is, is->subtitle_stream);
1203 avformat_close_input(&is->ic);
1205 packet_queue_destroy(&is->videoq);
1206 packet_queue_destroy(&is->audioq);
1207 packet_queue_destroy(&is->subtitleq);
1209 /* free all pictures */
1210 frame_queue_destory(&is->pictq);
1211 frame_queue_destory(&is->sampq);
1212 frame_queue_destory(&is->subpq);
1213 SDL_DestroyCond(is->continue_read_thread);
1214 #if !CONFIG_AVFILTER
1215 sws_freeContext(is->img_convert_ctx);
1217 sws_freeContext(is->sub_convert_ctx);
1218 av_free(is->filename);
1222 static void do_exit(VideoState *is)
1227 av_lockmgr_register(NULL);
1230 av_freep(&vfilters_list);
1232 avformat_network_deinit();
1236 av_log(NULL, AV_LOG_QUIET, "%s", "");
1240 static void sigterm_handler(int sig)
1245 static void set_default_window_size(int width, int height, AVRational sar)
1248 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1249 default_width = rect.w;
1250 default_height = rect.h;
1253 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1255 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1258 if (is_full_screen) flags |= SDL_FULLSCREEN;
1259 else flags |= SDL_RESIZABLE;
1261 if (vp && vp->width)
1262 set_default_window_size(vp->width, vp->height, vp->sar);
1264 if (is_full_screen && fs_screen_width) {
1265 w = fs_screen_width;
1266 h = fs_screen_height;
1267 } else if (!is_full_screen && screen_width) {
1274 w = FFMIN(16383, w);
1275 if (screen && is->width == screen->w && screen->w == w
1276 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1278 screen = SDL_SetVideoMode(w, h, 0, flags);
1280 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1284 window_title = input_filename;
1285 SDL_WM_SetCaption(window_title, window_title);
1287 is->width = screen->w;
1288 is->height = screen->h;
1293 /* display the current picture, if any */
1294 static void video_display(VideoState *is)
1297 video_open(is, 0, NULL);
1298 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1299 video_audio_display(is);
1300 else if (is->video_st)
1301 video_image_display(is);
1304 static double get_clock(Clock *c)
1306 if (*c->queue_serial != c->serial)
1311 double time = av_gettime_relative() / 1000000.0;
1312 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1316 static void set_clock_at(Clock *c, double pts, int serial, double time)
1319 c->last_updated = time;
1320 c->pts_drift = c->pts - time;
1324 static void set_clock(Clock *c, double pts, int serial)
1326 double time = av_gettime_relative() / 1000000.0;
1327 set_clock_at(c, pts, serial, time);
1330 static void set_clock_speed(Clock *c, double speed)
1332 set_clock(c, get_clock(c), c->serial);
1336 static void init_clock(Clock *c, int *queue_serial)
1340 c->queue_serial = queue_serial;
1341 set_clock(c, NAN, -1);
1344 static void sync_clock_to_slave(Clock *c, Clock *slave)
1346 double clock = get_clock(c);
1347 double slave_clock = get_clock(slave);
1348 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1349 set_clock(c, slave_clock, slave->serial);
1352 static int get_master_sync_type(VideoState *is) {
1353 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1355 return AV_SYNC_VIDEO_MASTER;
1357 return AV_SYNC_AUDIO_MASTER;
1358 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1360 return AV_SYNC_AUDIO_MASTER;
1362 return AV_SYNC_EXTERNAL_CLOCK;
1364 return AV_SYNC_EXTERNAL_CLOCK;
1368 /* get the current master clock value */
1369 static double get_master_clock(VideoState *is)
1373 switch (get_master_sync_type(is)) {
1374 case AV_SYNC_VIDEO_MASTER:
1375 val = get_clock(&is->vidclk);
1377 case AV_SYNC_AUDIO_MASTER:
1378 val = get_clock(&is->audclk);
1381 val = get_clock(&is->extclk);
1387 static void check_external_clock_speed(VideoState *is) {
1388 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1389 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1390 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1391 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1392 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1393 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1395 double speed = is->extclk.speed;
1397 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1401 /* seek in the stream */
1402 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1404 if (!is->seek_req) {
1407 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1409 is->seek_flags |= AVSEEK_FLAG_BYTE;
1411 SDL_CondSignal(is->continue_read_thread);
1415 /* pause or resume the video */
1416 static void stream_toggle_pause(VideoState *is)
1419 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1420 if (is->read_pause_return != AVERROR(ENOSYS)) {
1421 is->vidclk.paused = 0;
1423 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1425 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1426 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1429 static void toggle_pause(VideoState *is)
1431 stream_toggle_pause(is);
1435 static void toggle_mute(VideoState *is)
1437 is->muted = !is->muted;
1440 static void update_volume(VideoState *is, int sign, int step)
1442 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1445 static void step_to_next_frame(VideoState *is)
1447 /* if the stream is paused unpause it, then step */
1449 stream_toggle_pause(is);
1453 static double compute_target_delay(double delay, VideoState *is)
1455 double sync_threshold, diff = 0;
1457 /* update delay to follow master synchronisation source */
1458 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1459 /* if video is slave, we try to correct big delays by
1460 duplicating or deleting a frame */
1461 diff = get_clock(&is->vidclk) - get_master_clock(is);
1463 /* skip or repeat frame. We take into account the
1464 delay to compute the threshold. I still don't know
1465 if it is the best guess */
1466 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1467 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1468 if (diff <= -sync_threshold)
1469 delay = FFMAX(0, delay + diff);
1470 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1471 delay = delay + diff;
1472 else if (diff >= sync_threshold)
1477 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1483 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1484 if (vp->serial == nextvp->serial) {
1485 double duration = nextvp->pts - vp->pts;
1486 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1487 return vp->duration;
1495 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1496 /* update current video pts */
1497 set_clock(&is->vidclk, pts, serial);
1498 sync_clock_to_slave(&is->extclk, &is->vidclk);
1501 /* called to display each frame */
1502 static void video_refresh(void *opaque, double *remaining_time)
1504 VideoState *is = opaque;
1509 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1510 check_external_clock_speed(is);
1512 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1513 time = av_gettime_relative() / 1000000.0;
1514 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1516 is->last_vis_time = time;
1518 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1523 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1524 // nothing to do, no picture to display in the queue
1526 double last_duration, duration, delay;
1529 /* dequeue the picture */
1530 lastvp = frame_queue_peek_last(&is->pictq);
1531 vp = frame_queue_peek(&is->pictq);
1533 if (vp->serial != is->videoq.serial) {
1534 frame_queue_next(&is->pictq);
1538 if (lastvp->serial != vp->serial)
1539 is->frame_timer = av_gettime_relative() / 1000000.0;
1544 /* compute nominal last_duration */
1545 last_duration = vp_duration(is, lastvp, vp);
1546 delay = compute_target_delay(last_duration, is);
1548 time= av_gettime_relative()/1000000.0;
1549 if (time < is->frame_timer + delay) {
1550 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1554 is->frame_timer += delay;
1555 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1556 is->frame_timer = time;
1558 SDL_LockMutex(is->pictq.mutex);
1559 if (!isnan(vp->pts))
1560 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1561 SDL_UnlockMutex(is->pictq.mutex);
1563 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1564 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1565 duration = vp_duration(is, vp, nextvp);
1566 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1567 is->frame_drops_late++;
1568 frame_queue_next(&is->pictq);
1573 if (is->subtitle_st) {
1574 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1575 sp = frame_queue_peek(&is->subpq);
1577 if (frame_queue_nb_remaining(&is->subpq) > 1)
1578 sp2 = frame_queue_peek_next(&is->subpq);
1582 if (sp->serial != is->subtitleq.serial
1583 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1584 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1586 frame_queue_next(&is->subpq);
1593 frame_queue_next(&is->pictq);
1594 is->force_refresh = 1;
1596 if (is->step && !is->paused)
1597 stream_toggle_pause(is);
1600 /* display picture */
1601 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1604 is->force_refresh = 0;
1606 static int64_t last_time;
1608 int aqsize, vqsize, sqsize;
1611 cur_time = av_gettime_relative();
1612 if (!last_time || (cur_time - last_time) >= 30000) {
1617 aqsize = is->audioq.size;
1619 vqsize = is->videoq.size;
1620 if (is->subtitle_st)
1621 sqsize = is->subtitleq.size;
1623 if (is->audio_st && is->video_st)
1624 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1625 else if (is->video_st)
1626 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1627 else if (is->audio_st)
1628 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1629 av_log(NULL, AV_LOG_INFO,
1630 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1631 get_master_clock(is),
1632 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1634 is->frame_drops_early + is->frame_drops_late,
1638 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1639 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1641 last_time = cur_time;
1646 /* allocate a picture (needs to do that in main thread to avoid
1647 potential locking problems */
1648 static void alloc_picture(VideoState *is)
1653 vp = &is->pictq.queue[is->pictq.windex];
1657 video_open(is, 0, vp);
1659 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1662 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1663 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1664 /* SDL allocates a buffer smaller than requested if the video
1665 * overlay hardware is unable to support the requested size. */
1666 av_log(NULL, AV_LOG_FATAL,
1667 "Error: the video system does not support an image\n"
1668 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1669 "to reduce the image size.\n", vp->width, vp->height );
1673 SDL_LockMutex(is->pictq.mutex);
1675 SDL_CondSignal(is->pictq.cond);
1676 SDL_UnlockMutex(is->pictq.mutex);
1679 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1680 int i, width, height;
1682 for (i = 0; i < 3; i++) {
1689 if (bmp->pitches[i] > width) {
1690 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1691 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1697 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1701 #if defined(DEBUG_SYNC)
1702 printf("frame_type=%c pts=%0.3f\n",
1703 av_get_picture_type_char(src_frame->pict_type), pts);
1706 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1709 vp->sar = src_frame->sample_aspect_ratio;
1711 /* alloc or resize hardware picture buffer */
1712 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1713 vp->width != src_frame->width ||
1714 vp->height != src_frame->height) {
1719 vp->width = src_frame->width;
1720 vp->height = src_frame->height;
1722 /* the allocation must be done in the main thread to avoid
1723 locking problems. */
1724 event.type = FF_ALLOC_EVENT;
1725 event.user.data1 = is;
1726 SDL_PushEvent(&event);
1728 /* wait until the picture is allocated */
1729 SDL_LockMutex(is->pictq.mutex);
1730 while (!vp->allocated && !is->videoq.abort_request) {
1731 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1733 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1734 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1735 while (!vp->allocated && !is->abort_request) {
1736 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1739 SDL_UnlockMutex(is->pictq.mutex);
1741 if (is->videoq.abort_request)
1745 /* if the frame is not skipped, then display it */
1750 /* get a pointer on the bitmap */
1751 SDL_LockYUVOverlay (vp->bmp);
1753 data[0] = vp->bmp->pixels[0];
1754 data[1] = vp->bmp->pixels[2];
1755 data[2] = vp->bmp->pixels[1];
1757 linesize[0] = vp->bmp->pitches[0];
1758 linesize[1] = vp->bmp->pitches[2];
1759 linesize[2] = vp->bmp->pitches[1];
1762 // FIXME use direct rendering
1763 av_image_copy(data, linesize, (const uint8_t **)src_frame->data, src_frame->linesize,
1764 src_frame->format, vp->width, vp->height);
1767 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1769 const AVClass *class = sws_get_class();
1770 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1771 AV_OPT_SEARCH_FAKE_OBJ);
1772 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1778 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1779 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1780 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1781 if (!is->img_convert_ctx) {
1782 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1785 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1786 0, vp->height, data, linesize);
1788 /* workaround SDL PITCH_WORKAROUND */
1789 duplicate_right_border_pixels(vp->bmp);
1790 /* update the bitmap content */
1791 SDL_UnlockYUVOverlay(vp->bmp);
1794 vp->duration = duration;
1796 vp->serial = serial;
1798 /* now we can update the picture count */
1799 frame_queue_push(&is->pictq);
1804 static int get_video_frame(VideoState *is, AVFrame *frame)
1808 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1814 if (frame->pts != AV_NOPTS_VALUE)
1815 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1817 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1819 is->viddec_width = frame->width;
1820 is->viddec_height = frame->height;
1822 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1823 if (frame->pts != AV_NOPTS_VALUE) {
1824 double diff = dpts - get_master_clock(is);
1825 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1826 diff - is->frame_last_filter_delay < 0 &&
1827 is->viddec.pkt_serial == is->vidclk.serial &&
1828 is->videoq.nb_packets) {
1829 is->frame_drops_early++;
1830 av_frame_unref(frame);
1841 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1842 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1845 int nb_filters = graph->nb_filters;
1846 AVFilterInOut *outputs = NULL, *inputs = NULL;
1849 outputs = avfilter_inout_alloc();
1850 inputs = avfilter_inout_alloc();
1851 if (!outputs || !inputs) {
1852 ret = AVERROR(ENOMEM);
1856 outputs->name = av_strdup("in");
1857 outputs->filter_ctx = source_ctx;
1858 outputs->pad_idx = 0;
1859 outputs->next = NULL;
1861 inputs->name = av_strdup("out");
1862 inputs->filter_ctx = sink_ctx;
1863 inputs->pad_idx = 0;
1864 inputs->next = NULL;
1866 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1869 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1873 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1874 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1875 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1877 ret = avfilter_graph_config(graph, NULL);
1879 avfilter_inout_free(&outputs);
1880 avfilter_inout_free(&inputs);
1884 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1886 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1887 char sws_flags_str[512] = "";
1888 char buffersrc_args[256];
1890 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1891 AVCodecParameters *codecpar = is->video_st->codecpar;
1892 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1893 AVDictionaryEntry *e = NULL;
1895 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1896 if (!strcmp(e->key, "sws_flags")) {
1897 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1899 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1901 if (strlen(sws_flags_str))
1902 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1904 graph->scale_sws_opts = av_strdup(sws_flags_str);
1906 snprintf(buffersrc_args, sizeof(buffersrc_args),
1907 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1908 frame->width, frame->height, frame->format,
1909 is->video_st->time_base.num, is->video_st->time_base.den,
1910 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1911 if (fr.num && fr.den)
1912 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1914 if ((ret = avfilter_graph_create_filter(&filt_src,
1915 avfilter_get_by_name("buffer"),
1916 "ffplay_buffer", buffersrc_args, NULL,
1920 ret = avfilter_graph_create_filter(&filt_out,
1921 avfilter_get_by_name("buffersink"),
1922 "ffplay_buffersink", NULL, NULL, graph);
1926 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1929 last_filter = filt_out;
1931 /* Note: this macro adds a filter before the lastly added filter, so the
1932 * processing order of the filters is in reverse */
1933 #define INSERT_FILT(name, arg) do { \
1934 AVFilterContext *filt_ctx; \
1936 ret = avfilter_graph_create_filter(&filt_ctx, \
1937 avfilter_get_by_name(name), \
1938 "ffplay_" name, arg, NULL, graph); \
1942 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1946 last_filter = filt_ctx; \
1949 /* SDL YUV code is not handling odd width/height for some driver
1950 * combinations, therefore we crop the picture to an even width/height. */
1951 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1954 double theta = get_rotation(is->video_st);
1956 if (fabs(theta - 90) < 1.0) {
1957 INSERT_FILT("transpose", "clock");
1958 } else if (fabs(theta - 180) < 1.0) {
1959 INSERT_FILT("hflip", NULL);
1960 INSERT_FILT("vflip", NULL);
1961 } else if (fabs(theta - 270) < 1.0) {
1962 INSERT_FILT("transpose", "cclock");
1963 } else if (fabs(theta) > 1.0) {
1964 char rotate_buf[64];
1965 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1966 INSERT_FILT("rotate", rotate_buf);
1970 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1973 is->in_video_filter = filt_src;
1974 is->out_video_filter = filt_out;
1980 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1982 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1983 int sample_rates[2] = { 0, -1 };
1984 int64_t channel_layouts[2] = { 0, -1 };
1985 int channels[2] = { 0, -1 };
1986 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1987 char aresample_swr_opts[512] = "";
1988 AVDictionaryEntry *e = NULL;
1989 char asrc_args[256];
1992 avfilter_graph_free(&is->agraph);
1993 if (!(is->agraph = avfilter_graph_alloc()))
1994 return AVERROR(ENOMEM);
1996 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1997 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1998 if (strlen(aresample_swr_opts))
1999 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2000 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2002 ret = snprintf(asrc_args, sizeof(asrc_args),
2003 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2004 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2005 is->audio_filter_src.channels,
2006 1, is->audio_filter_src.freq);
2007 if (is->audio_filter_src.channel_layout)
2008 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2009 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2011 ret = avfilter_graph_create_filter(&filt_asrc,
2012 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2013 asrc_args, NULL, is->agraph);
2018 ret = avfilter_graph_create_filter(&filt_asink,
2019 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2020 NULL, NULL, is->agraph);
2024 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2026 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2029 if (force_output_format) {
2030 channel_layouts[0] = is->audio_tgt.channel_layout;
2031 channels [0] = is->audio_tgt.channels;
2032 sample_rates [0] = is->audio_tgt.freq;
2033 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2035 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2037 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2039 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2044 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2047 is->in_audio_filter = filt_asrc;
2048 is->out_audio_filter = filt_asink;
2052 avfilter_graph_free(&is->agraph);
2055 #endif /* CONFIG_AVFILTER */
2057 static int audio_thread(void *arg)
2059 VideoState *is = arg;
2060 AVFrame *frame = av_frame_alloc();
2063 int last_serial = -1;
2064 int64_t dec_channel_layout;
2072 return AVERROR(ENOMEM);
2075 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2079 tb = (AVRational){1, frame->sample_rate};
2082 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2085 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2086 frame->format, av_frame_get_channels(frame)) ||
2087 is->audio_filter_src.channel_layout != dec_channel_layout ||
2088 is->audio_filter_src.freq != frame->sample_rate ||
2089 is->auddec.pkt_serial != last_serial;
2092 char buf1[1024], buf2[1024];
2093 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2094 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2095 av_log(NULL, AV_LOG_DEBUG,
2096 "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",
2097 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2098 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2100 is->audio_filter_src.fmt = frame->format;
2101 is->audio_filter_src.channels = av_frame_get_channels(frame);
2102 is->audio_filter_src.channel_layout = dec_channel_layout;
2103 is->audio_filter_src.freq = frame->sample_rate;
2104 last_serial = is->auddec.pkt_serial;
2106 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2110 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2113 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2114 tb = is->out_audio_filter->inputs[0]->time_base;
2116 if (!(af = frame_queue_peek_writable(&is->sampq)))
2119 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2120 af->pos = av_frame_get_pkt_pos(frame);
2121 af->serial = is->auddec.pkt_serial;
2122 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2124 av_frame_move_ref(af->frame, frame);
2125 frame_queue_push(&is->sampq);
2128 if (is->audioq.serial != is->auddec.pkt_serial)
2131 if (ret == AVERROR_EOF)
2132 is->auddec.finished = is->auddec.pkt_serial;
2135 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2138 avfilter_graph_free(&is->agraph);
2140 av_frame_free(&frame);
2144 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2146 packet_queue_start(d->queue);
2147 d->decoder_tid = SDL_CreateThread(fn, arg);
2148 if (!d->decoder_tid) {
2149 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2150 return AVERROR(ENOMEM);
2155 static int video_thread(void *arg)
2157 VideoState *is = arg;
2158 AVFrame *frame = av_frame_alloc();
2162 AVRational tb = is->video_st->time_base;
2163 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2166 AVFilterGraph *graph = avfilter_graph_alloc();
2167 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2170 enum AVPixelFormat last_format = -2;
2171 int last_serial = -1;
2172 int last_vfilter_idx = 0;
2174 av_frame_free(&frame);
2175 return AVERROR(ENOMEM);
2182 avfilter_graph_free(&graph);
2184 return AVERROR(ENOMEM);
2188 ret = get_video_frame(is, frame);
2195 if ( last_w != frame->width
2196 || last_h != frame->height
2197 || last_format != frame->format
2198 || last_serial != is->viddec.pkt_serial
2199 || last_vfilter_idx != is->vfilter_idx) {
2200 av_log(NULL, AV_LOG_DEBUG,
2201 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2203 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2204 frame->width, frame->height,
2205 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2206 avfilter_graph_free(&graph);
2207 graph = avfilter_graph_alloc();
2208 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2210 event.type = FF_QUIT_EVENT;
2211 event.user.data1 = is;
2212 SDL_PushEvent(&event);
2215 filt_in = is->in_video_filter;
2216 filt_out = is->out_video_filter;
2217 last_w = frame->width;
2218 last_h = frame->height;
2219 last_format = frame->format;
2220 last_serial = is->viddec.pkt_serial;
2221 last_vfilter_idx = is->vfilter_idx;
2222 frame_rate = filt_out->inputs[0]->frame_rate;
2225 ret = av_buffersrc_add_frame(filt_in, frame);
2230 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2232 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2234 if (ret == AVERROR_EOF)
2235 is->viddec.finished = is->viddec.pkt_serial;
2240 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2241 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2242 is->frame_last_filter_delay = 0;
2243 tb = filt_out->inputs[0]->time_base;
2245 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2246 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2247 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2248 av_frame_unref(frame);
2258 avfilter_graph_free(&graph);
2260 av_frame_free(&frame);
2264 static int subtitle_thread(void *arg)
2266 VideoState *is = arg;
2273 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2276 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2281 if (got_subtitle && sp->sub.format == 0) {
2282 if (sp->sub.pts != AV_NOPTS_VALUE)
2283 pts = sp->sub.pts / (double)AV_TIME_BASE;
2285 sp->serial = is->subdec.pkt_serial;
2286 if (!(sp->subrects = av_mallocz_array(sp->sub.num_rects, sizeof(AVSubtitleRect*)))) {
2287 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subrects\n");
2291 for (i = 0; i < sp->sub.num_rects; i++)
2293 int in_w = sp->sub.rects[i]->w;
2294 int in_h = sp->sub.rects[i]->h;
2295 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2296 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2297 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2298 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2300 if (!(sp->subrects[i] = av_mallocz(sizeof(AVSubtitleRect))) ||
2301 av_image_alloc(sp->subrects[i]->data, sp->subrects[i]->linesize, out_w, out_h, AV_PIX_FMT_YUVA420P, 16) < 0) {
2302 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subtitle data\n");
2306 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2307 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2308 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2309 if (!is->sub_convert_ctx) {
2310 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2313 sws_scale(is->sub_convert_ctx,
2314 (void*)sp->sub.rects[i]->data, sp->sub.rects[i]->linesize,
2315 0, in_h, sp->subrects[i]->data, sp->subrects[i]->linesize);
2317 sp->subrects[i]->w = out_w;
2318 sp->subrects[i]->h = out_h;
2319 sp->subrects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2320 sp->subrects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2323 /* now we can update the picture count */
2324 frame_queue_push(&is->subpq);
2325 } else if (got_subtitle) {
2326 avsubtitle_free(&sp->sub);
2332 /* copy samples for viewing in editor window */
2333 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2337 size = samples_size / sizeof(short);
2339 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2342 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2344 is->sample_array_index += len;
2345 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2346 is->sample_array_index = 0;
2351 /* return the wanted number of samples to get better sync if sync_type is video
2352 * or external master clock */
2353 static int synchronize_audio(VideoState *is, int nb_samples)
2355 int wanted_nb_samples = nb_samples;
2357 /* if not master, then we try to remove or add samples to correct the clock */
2358 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2359 double diff, avg_diff;
2360 int min_nb_samples, max_nb_samples;
2362 diff = get_clock(&is->audclk) - get_master_clock(is);
2364 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2365 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2366 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2367 /* not enough measures to have a correct estimate */
2368 is->audio_diff_avg_count++;
2370 /* estimate the A-V difference */
2371 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2373 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2374 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2375 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2376 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2377 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2379 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2380 diff, avg_diff, wanted_nb_samples - nb_samples,
2381 is->audio_clock, is->audio_diff_threshold);
2384 /* too big difference : may be initial PTS errors, so
2386 is->audio_diff_avg_count = 0;
2387 is->audio_diff_cum = 0;
2391 return wanted_nb_samples;
2395 * Decode one audio frame and return its uncompressed size.
2397 * The processed audio frame is decoded, converted if required, and
2398 * stored in is->audio_buf, with size in bytes given by the return
2401 static int audio_decode_frame(VideoState *is)
2403 int data_size, resampled_data_size;
2404 int64_t dec_channel_layout;
2405 av_unused double audio_clock0;
2406 int wanted_nb_samples;
2414 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2415 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2420 if (!(af = frame_queue_peek_readable(&is->sampq)))
2422 frame_queue_next(&is->sampq);
2423 } while (af->serial != is->audioq.serial);
2425 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2426 af->frame->nb_samples,
2427 af->frame->format, 1);
2429 dec_channel_layout =
2430 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2431 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2432 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2434 if (af->frame->format != is->audio_src.fmt ||
2435 dec_channel_layout != is->audio_src.channel_layout ||
2436 af->frame->sample_rate != is->audio_src.freq ||
2437 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2438 swr_free(&is->swr_ctx);
2439 is->swr_ctx = swr_alloc_set_opts(NULL,
2440 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2441 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2443 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2444 av_log(NULL, AV_LOG_ERROR,
2445 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2446 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2447 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2448 swr_free(&is->swr_ctx);
2451 is->audio_src.channel_layout = dec_channel_layout;
2452 is->audio_src.channels = av_frame_get_channels(af->frame);
2453 is->audio_src.freq = af->frame->sample_rate;
2454 is->audio_src.fmt = af->frame->format;
2458 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2459 uint8_t **out = &is->audio_buf1;
2460 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2461 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2464 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2467 if (wanted_nb_samples != af->frame->nb_samples) {
2468 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2469 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2470 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2474 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2475 if (!is->audio_buf1)
2476 return AVERROR(ENOMEM);
2477 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2479 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2482 if (len2 == out_count) {
2483 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2484 if (swr_init(is->swr_ctx) < 0)
2485 swr_free(&is->swr_ctx);
2487 is->audio_buf = is->audio_buf1;
2488 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2490 is->audio_buf = af->frame->data[0];
2491 resampled_data_size = data_size;
2494 audio_clock0 = is->audio_clock;
2495 /* update the audio clock with the pts */
2496 if (!isnan(af->pts))
2497 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2499 is->audio_clock = NAN;
2500 is->audio_clock_serial = af->serial;
2503 static double last_clock;
2504 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2505 is->audio_clock - last_clock,
2506 is->audio_clock, audio_clock0);
2507 last_clock = is->audio_clock;
2510 return resampled_data_size;
2513 /* prepare a new audio buffer */
2514 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2516 VideoState *is = opaque;
2517 int audio_size, len1;
2519 audio_callback_time = av_gettime_relative();
2522 if (is->audio_buf_index >= is->audio_buf_size) {
2523 audio_size = audio_decode_frame(is);
2524 if (audio_size < 0) {
2525 /* if error, just output silence */
2526 is->audio_buf = NULL;
2527 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2529 if (is->show_mode != SHOW_MODE_VIDEO)
2530 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2531 is->audio_buf_size = audio_size;
2533 is->audio_buf_index = 0;
2535 len1 = is->audio_buf_size - is->audio_buf_index;
2538 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2539 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2541 memset(stream, 0, len1);
2542 if (!is->muted && is->audio_buf)
2543 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2547 is->audio_buf_index += len1;
2549 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2550 /* Let's assume the audio driver that is used by SDL has two periods. */
2551 if (!isnan(is->audio_clock)) {
2552 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);
2553 sync_clock_to_slave(&is->extclk, &is->audclk);
2557 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2559 SDL_AudioSpec wanted_spec, spec;
2561 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2562 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2563 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2565 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2567 wanted_nb_channels = atoi(env);
2568 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2570 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2571 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2572 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2574 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2575 wanted_spec.channels = wanted_nb_channels;
2576 wanted_spec.freq = wanted_sample_rate;
2577 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2578 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2581 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2582 next_sample_rate_idx--;
2583 wanted_spec.format = AUDIO_S16SYS;
2584 wanted_spec.silence = 0;
2585 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2586 wanted_spec.callback = sdl_audio_callback;
2587 wanted_spec.userdata = opaque;
2588 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2589 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2590 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2591 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2592 if (!wanted_spec.channels) {
2593 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2594 wanted_spec.channels = wanted_nb_channels;
2595 if (!wanted_spec.freq) {
2596 av_log(NULL, AV_LOG_ERROR,
2597 "No more combinations to try, audio open failed\n");
2601 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2603 if (spec.format != AUDIO_S16SYS) {
2604 av_log(NULL, AV_LOG_ERROR,
2605 "SDL advised audio format %d is not supported!\n", spec.format);
2608 if (spec.channels != wanted_spec.channels) {
2609 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2610 if (!wanted_channel_layout) {
2611 av_log(NULL, AV_LOG_ERROR,
2612 "SDL advised channel count %d is not supported!\n", spec.channels);
2617 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2618 audio_hw_params->freq = spec.freq;
2619 audio_hw_params->channel_layout = wanted_channel_layout;
2620 audio_hw_params->channels = spec.channels;
2621 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2622 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);
2623 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2624 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2630 /* open a given stream. Return 0 if OK */
2631 static int stream_component_open(VideoState *is, int stream_index)
2633 AVFormatContext *ic = is->ic;
2634 AVCodecContext *avctx;
2636 const char *forced_codec_name = NULL;
2637 AVDictionary *opts = NULL;
2638 AVDictionaryEntry *t = NULL;
2639 int sample_rate, nb_channels;
2640 int64_t channel_layout;
2642 int stream_lowres = lowres;
2644 if (stream_index < 0 || stream_index >= ic->nb_streams)
2647 avctx = avcodec_alloc_context3(NULL);
2649 return AVERROR(ENOMEM);
2651 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2654 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2656 codec = avcodec_find_decoder(avctx->codec_id);
2658 switch(avctx->codec_type){
2659 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2660 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2661 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2663 if (forced_codec_name)
2664 codec = avcodec_find_decoder_by_name(forced_codec_name);
2666 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2667 "No codec could be found with name '%s'\n", forced_codec_name);
2668 else av_log(NULL, AV_LOG_WARNING,
2669 "No codec could be found with id %d\n", avctx->codec_id);
2670 ret = AVERROR(EINVAL);
2674 avctx->codec_id = codec->id;
2675 if(stream_lowres > av_codec_get_max_lowres(codec)){
2676 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2677 av_codec_get_max_lowres(codec));
2678 stream_lowres = av_codec_get_max_lowres(codec);
2680 av_codec_set_lowres(avctx, stream_lowres);
2683 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2686 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2688 if(codec->capabilities & AV_CODEC_CAP_DR1)
2689 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2692 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2693 if (!av_dict_get(opts, "threads", NULL, 0))
2694 av_dict_set(&opts, "threads", "auto", 0);
2696 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2697 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2698 av_dict_set(&opts, "refcounted_frames", "1", 0);
2699 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2702 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2703 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2704 ret = AVERROR_OPTION_NOT_FOUND;
2709 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2710 switch (avctx->codec_type) {
2711 case AVMEDIA_TYPE_AUDIO:
2716 is->audio_filter_src.freq = avctx->sample_rate;
2717 is->audio_filter_src.channels = avctx->channels;
2718 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2719 is->audio_filter_src.fmt = avctx->sample_fmt;
2720 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2722 link = is->out_audio_filter->inputs[0];
2723 sample_rate = link->sample_rate;
2724 nb_channels = link->channels;
2725 channel_layout = link->channel_layout;
2728 sample_rate = avctx->sample_rate;
2729 nb_channels = avctx->channels;
2730 channel_layout = avctx->channel_layout;
2733 /* prepare audio output */
2734 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2736 is->audio_hw_buf_size = ret;
2737 is->audio_src = is->audio_tgt;
2738 is->audio_buf_size = 0;
2739 is->audio_buf_index = 0;
2741 /* init averaging filter */
2742 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2743 is->audio_diff_avg_count = 0;
2744 /* since we do not have a precise anough audio fifo fullness,
2745 we correct audio sync only if larger than this threshold */
2746 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2748 is->audio_stream = stream_index;
2749 is->audio_st = ic->streams[stream_index];
2751 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2752 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2753 is->auddec.start_pts = is->audio_st->start_time;
2754 is->auddec.start_pts_tb = is->audio_st->time_base;
2756 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2760 case AVMEDIA_TYPE_VIDEO:
2761 is->video_stream = stream_index;
2762 is->video_st = ic->streams[stream_index];
2764 is->viddec_width = avctx->width;
2765 is->viddec_height = avctx->height;
2767 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2768 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2770 is->queue_attachments_req = 1;
2772 case AVMEDIA_TYPE_SUBTITLE:
2773 is->subtitle_stream = stream_index;
2774 is->subtitle_st = ic->streams[stream_index];
2776 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2777 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2786 avcodec_free_context(&avctx);
2788 av_dict_free(&opts);
2793 static int decode_interrupt_cb(void *ctx)
2795 VideoState *is = ctx;
2796 return is->abort_request;
2799 static int is_realtime(AVFormatContext *s)
2801 if( !strcmp(s->iformat->name, "rtp")
2802 || !strcmp(s->iformat->name, "rtsp")
2803 || !strcmp(s->iformat->name, "sdp")
2807 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2808 || !strncmp(s->filename, "udp:", 4)
2815 /* this thread gets the stream from the disk or the network */
2816 static int read_thread(void *arg)
2818 VideoState *is = arg;
2819 AVFormatContext *ic = NULL;
2821 int st_index[AVMEDIA_TYPE_NB];
2822 AVPacket pkt1, *pkt = &pkt1;
2823 int64_t stream_start_time;
2824 int pkt_in_play_range = 0;
2825 AVDictionaryEntry *t;
2826 AVDictionary **opts;
2827 int orig_nb_streams;
2828 SDL_mutex *wait_mutex = SDL_CreateMutex();
2829 int scan_all_pmts_set = 0;
2833 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2834 ret = AVERROR(ENOMEM);
2838 memset(st_index, -1, sizeof(st_index));
2839 is->last_video_stream = is->video_stream = -1;
2840 is->last_audio_stream = is->audio_stream = -1;
2841 is->last_subtitle_stream = is->subtitle_stream = -1;
2844 ic = avformat_alloc_context();
2846 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2847 ret = AVERROR(ENOMEM);
2850 ic->interrupt_callback.callback = decode_interrupt_cb;
2851 ic->interrupt_callback.opaque = is;
2852 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2853 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2854 scan_all_pmts_set = 1;
2856 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2858 print_error(is->filename, err);
2862 if (scan_all_pmts_set)
2863 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2865 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2866 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2867 ret = AVERROR_OPTION_NOT_FOUND;
2873 ic->flags |= AVFMT_FLAG_GENPTS;
2875 av_format_inject_global_side_data(ic);
2877 opts = setup_find_stream_info_opts(ic, codec_opts);
2878 orig_nb_streams = ic->nb_streams;
2880 err = avformat_find_stream_info(ic, opts);
2882 for (i = 0; i < orig_nb_streams; i++)
2883 av_dict_free(&opts[i]);
2887 av_log(NULL, AV_LOG_WARNING,
2888 "%s: could not find codec parameters\n", is->filename);
2894 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2896 if (seek_by_bytes < 0)
2897 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2899 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2901 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2902 window_title = av_asprintf("%s - %s", t->value, input_filename);
2904 /* if seeking requested, we execute it */
2905 if (start_time != AV_NOPTS_VALUE) {
2908 timestamp = start_time;
2909 /* add the stream start time */
2910 if (ic->start_time != AV_NOPTS_VALUE)
2911 timestamp += ic->start_time;
2912 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2914 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2915 is->filename, (double)timestamp / AV_TIME_BASE);
2919 is->realtime = is_realtime(ic);
2922 av_dump_format(ic, 0, is->filename, 0);
2924 for (i = 0; i < ic->nb_streams; i++) {
2925 AVStream *st = ic->streams[i];
2926 enum AVMediaType type = st->codecpar->codec_type;
2927 st->discard = AVDISCARD_ALL;
2928 if (wanted_stream_spec[type] && st_index[type] == -1)
2929 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2932 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2933 if (wanted_stream_spec[i] && st_index[i] == -1) {
2934 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));
2935 st_index[i] = INT_MAX;
2940 st_index[AVMEDIA_TYPE_VIDEO] =
2941 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2942 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2944 st_index[AVMEDIA_TYPE_AUDIO] =
2945 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2946 st_index[AVMEDIA_TYPE_AUDIO],
2947 st_index[AVMEDIA_TYPE_VIDEO],
2949 if (!video_disable && !subtitle_disable)
2950 st_index[AVMEDIA_TYPE_SUBTITLE] =
2951 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2952 st_index[AVMEDIA_TYPE_SUBTITLE],
2953 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2954 st_index[AVMEDIA_TYPE_AUDIO] :
2955 st_index[AVMEDIA_TYPE_VIDEO]),
2958 is->show_mode = show_mode;
2959 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2960 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2961 AVCodecParameters *codecpar = st->codecpar;
2962 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2963 if (codecpar->width)
2964 set_default_window_size(codecpar->width, codecpar->height, sar);
2967 /* open the streams */
2968 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2969 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2973 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2974 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2976 if (is->show_mode == SHOW_MODE_NONE)
2977 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2979 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2980 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2983 if (is->video_stream < 0 && is->audio_stream < 0) {
2984 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2990 if (infinite_buffer < 0 && is->realtime)
2991 infinite_buffer = 1;
2994 if (is->abort_request)
2996 if (is->paused != is->last_paused) {
2997 is->last_paused = is->paused;
2999 is->read_pause_return = av_read_pause(ic);
3003 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3005 (!strcmp(ic->iformat->name, "rtsp") ||
3006 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3007 /* wait 10 ms to avoid trying to get another packet */
3014 int64_t seek_target = is->seek_pos;
3015 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3016 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3017 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3018 // of the seek_pos/seek_rel variables
3020 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3022 av_log(NULL, AV_LOG_ERROR,
3023 "%s: error while seeking\n", is->ic->filename);
3025 if (is->audio_stream >= 0) {
3026 packet_queue_flush(&is->audioq);
3027 packet_queue_put(&is->audioq, &flush_pkt);
3029 if (is->subtitle_stream >= 0) {
3030 packet_queue_flush(&is->subtitleq);
3031 packet_queue_put(&is->subtitleq, &flush_pkt);
3033 if (is->video_stream >= 0) {
3034 packet_queue_flush(&is->videoq);
3035 packet_queue_put(&is->videoq, &flush_pkt);
3037 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3038 set_clock(&is->extclk, NAN, 0);
3040 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3044 is->queue_attachments_req = 1;
3047 step_to_next_frame(is);
3049 if (is->queue_attachments_req) {
3050 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3052 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3054 packet_queue_put(&is->videoq, ©);
3055 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3057 is->queue_attachments_req = 0;
3060 /* if the queue are full, no need to read more */
3061 if (infinite_buffer<1 &&
3062 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3063 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3064 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3065 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3066 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3068 SDL_LockMutex(wait_mutex);
3069 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3070 SDL_UnlockMutex(wait_mutex);
3074 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3075 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3076 if (loop != 1 && (!loop || --loop)) {
3077 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3078 } else if (autoexit) {
3083 ret = av_read_frame(ic, pkt);
3085 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3086 if (is->video_stream >= 0)
3087 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3088 if (is->audio_stream >= 0)
3089 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3090 if (is->subtitle_stream >= 0)
3091 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3094 if (ic->pb && ic->pb->error)
3096 SDL_LockMutex(wait_mutex);
3097 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3098 SDL_UnlockMutex(wait_mutex);
3103 /* check if packet is in play range specified by user, then queue, otherwise discard */
3104 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3105 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3106 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3107 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3108 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3109 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3110 <= ((double)duration / 1000000);
3111 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3112 packet_queue_put(&is->audioq, pkt);
3113 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3114 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3115 packet_queue_put(&is->videoq, pkt);
3116 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3117 packet_queue_put(&is->subtitleq, pkt);
3119 av_packet_unref(pkt);
3126 avformat_close_input(&ic);
3131 event.type = FF_QUIT_EVENT;
3132 event.user.data1 = is;
3133 SDL_PushEvent(&event);
3135 SDL_DestroyMutex(wait_mutex);
3139 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3143 is = av_mallocz(sizeof(VideoState));
3146 is->filename = av_strdup(filename);
3149 is->iformat = iformat;
3153 /* start video display */
3154 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3156 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3158 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3161 if (packet_queue_init(&is->videoq) < 0 ||
3162 packet_queue_init(&is->audioq) < 0 ||
3163 packet_queue_init(&is->subtitleq) < 0)
3166 if (!(is->continue_read_thread = SDL_CreateCond())) {
3167 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3171 init_clock(&is->vidclk, &is->videoq.serial);
3172 init_clock(&is->audclk, &is->audioq.serial);
3173 init_clock(&is->extclk, &is->extclk.serial);
3174 is->audio_clock_serial = -1;
3175 is->audio_volume = SDL_MIX_MAXVOLUME;
3177 is->av_sync_type = av_sync_type;
3178 is->read_tid = SDL_CreateThread(read_thread, is);
3179 if (!is->read_tid) {
3180 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3188 static void stream_cycle_channel(VideoState *is, int codec_type)
3190 AVFormatContext *ic = is->ic;
3191 int start_index, stream_index;
3194 AVProgram *p = NULL;
3195 int nb_streams = is->ic->nb_streams;
3197 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3198 start_index = is->last_video_stream;
3199 old_index = is->video_stream;
3200 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3201 start_index = is->last_audio_stream;
3202 old_index = is->audio_stream;
3204 start_index = is->last_subtitle_stream;
3205 old_index = is->subtitle_stream;
3207 stream_index = start_index;
3209 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3210 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3212 nb_streams = p->nb_stream_indexes;
3213 for (start_index = 0; start_index < nb_streams; start_index++)
3214 if (p->stream_index[start_index] == stream_index)
3216 if (start_index == nb_streams)
3218 stream_index = start_index;
3223 if (++stream_index >= nb_streams)
3225 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3228 is->last_subtitle_stream = -1;
3231 if (start_index == -1)
3235 if (stream_index == start_index)
3237 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3238 if (st->codecpar->codec_type == codec_type) {
3239 /* check that parameters are OK */
3240 switch (codec_type) {
3241 case AVMEDIA_TYPE_AUDIO:
3242 if (st->codecpar->sample_rate != 0 &&
3243 st->codecpar->channels != 0)
3246 case AVMEDIA_TYPE_VIDEO:
3247 case AVMEDIA_TYPE_SUBTITLE:
3255 if (p && stream_index != -1)
3256 stream_index = p->stream_index[stream_index];
3257 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3258 av_get_media_type_string(codec_type),
3262 stream_component_close(is, old_index);
3263 stream_component_open(is, stream_index);
3267 static void toggle_full_screen(VideoState *is)
3269 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3270 /* OS X needs to reallocate the SDL overlays */
3272 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3273 is->pictq.queue[i].reallocate = 1;
3275 is_full_screen = !is_full_screen;
3276 video_open(is, 1, NULL);
3279 static void toggle_audio_display(VideoState *is)
3281 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3282 int next = is->show_mode;
3284 next = (next + 1) % SHOW_MODE_NB;
3285 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3286 if (is->show_mode != next) {
3287 fill_rectangle(screen,
3288 is->xleft, is->ytop, is->width, is->height,
3290 is->force_refresh = 1;
3291 is->show_mode = next;
3295 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3296 double remaining_time = 0.0;
3298 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3299 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3303 if (remaining_time > 0.0)
3304 av_usleep((int64_t)(remaining_time * 1000000.0));
3305 remaining_time = REFRESH_RATE;
3306 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3307 video_refresh(is, &remaining_time);
3312 static void seek_chapter(VideoState *is, int incr)
3314 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3317 if (!is->ic->nb_chapters)
3320 /* find the current chapter */
3321 for (i = 0; i < is->ic->nb_chapters; i++) {
3322 AVChapter *ch = is->ic->chapters[i];
3323 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3331 if (i >= is->ic->nb_chapters)
3334 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3335 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3336 AV_TIME_BASE_Q), 0, 0);
3339 /* handle an event sent by the GUI */
3340 static void event_loop(VideoState *cur_stream)
3343 double incr, pos, frac;
3347 refresh_loop_wait_event(cur_stream, &event);
3348 switch (event.type) {
3350 if (exit_on_keydown) {
3351 do_exit(cur_stream);
3354 switch (event.key.keysym.sym) {
3357 do_exit(cur_stream);
3360 toggle_full_screen(cur_stream);
3361 cur_stream->force_refresh = 1;
3365 toggle_pause(cur_stream);
3368 toggle_mute(cur_stream);
3370 case SDLK_KP_MULTIPLY:
3372 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3374 case SDLK_KP_DIVIDE:
3376 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3378 case SDLK_s: // S: Step to next frame
3379 step_to_next_frame(cur_stream);
3382 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3385 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3388 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3389 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3390 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3393 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3397 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3398 if (++cur_stream->vfilter_idx >= nb_vfilters)
3399 cur_stream->vfilter_idx = 0;
3401 cur_stream->vfilter_idx = 0;
3402 toggle_audio_display(cur_stream);
3405 toggle_audio_display(cur_stream);
3409 if (cur_stream->ic->nb_chapters <= 1) {
3413 seek_chapter(cur_stream, 1);
3416 if (cur_stream->ic->nb_chapters <= 1) {
3420 seek_chapter(cur_stream, -1);
3434 if (seek_by_bytes) {
3436 if (pos < 0 && cur_stream->video_stream >= 0)
3437 pos = frame_queue_last_pos(&cur_stream->pictq);
3438 if (pos < 0 && cur_stream->audio_stream >= 0)
3439 pos = frame_queue_last_pos(&cur_stream->sampq);
3441 pos = avio_tell(cur_stream->ic->pb);
3442 if (cur_stream->ic->bit_rate)
3443 incr *= cur_stream->ic->bit_rate / 8.0;
3447 stream_seek(cur_stream, pos, incr, 1);
3449 pos = get_master_clock(cur_stream);
3451 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3453 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3454 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3455 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3462 case SDL_VIDEOEXPOSE:
3463 cur_stream->force_refresh = 1;
3465 case SDL_MOUSEBUTTONDOWN:
3466 if (exit_on_mousedown) {
3467 do_exit(cur_stream);
3470 if (event.button.button == SDL_BUTTON_LEFT) {
3471 static int64_t last_mouse_left_click = 0;
3472 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3473 toggle_full_screen(cur_stream);
3474 cur_stream->force_refresh = 1;
3475 last_mouse_left_click = 0;
3477 last_mouse_left_click = av_gettime_relative();
3480 case SDL_MOUSEMOTION:
3481 if (cursor_hidden) {
3485 cursor_last_shown = av_gettime_relative();
3486 if (event.type == SDL_MOUSEBUTTONDOWN) {
3487 if (event.button.button != SDL_BUTTON_RIGHT)
3491 if (!(event.motion.state & SDL_BUTTON_RMASK))
3495 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3496 uint64_t size = avio_size(cur_stream->ic->pb);
3497 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3501 int tns, thh, tmm, tss;
3502 tns = cur_stream->ic->duration / 1000000LL;
3504 tmm = (tns % 3600) / 60;
3506 frac = x / cur_stream->width;
3509 mm = (ns % 3600) / 60;
3511 av_log(NULL, AV_LOG_INFO,
3512 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3513 hh, mm, ss, thh, tmm, tss);
3514 ts = frac * cur_stream->ic->duration;
3515 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3516 ts += cur_stream->ic->start_time;
3517 stream_seek(cur_stream, ts, 0, 0);
3520 case SDL_VIDEORESIZE:
3521 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3522 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3524 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3525 do_exit(cur_stream);
3527 screen_width = cur_stream->width = screen->w;
3528 screen_height = cur_stream->height = screen->h;
3529 cur_stream->force_refresh = 1;
3533 do_exit(cur_stream);
3535 case FF_ALLOC_EVENT:
3536 alloc_picture(event.user.data1);
3544 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3546 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3547 return opt_default(NULL, "video_size", arg);
3550 static int opt_width(void *optctx, const char *opt, const char *arg)
3552 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3556 static int opt_height(void *optctx, const char *opt, const char *arg)
3558 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3562 static int opt_format(void *optctx, const char *opt, const char *arg)
3564 file_iformat = av_find_input_format(arg);
3565 if (!file_iformat) {
3566 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3567 return AVERROR(EINVAL);
3572 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3574 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3575 return opt_default(NULL, "pixel_format", arg);
3578 static int opt_sync(void *optctx, const char *opt, const char *arg)
3580 if (!strcmp(arg, "audio"))
3581 av_sync_type = AV_SYNC_AUDIO_MASTER;
3582 else if (!strcmp(arg, "video"))
3583 av_sync_type = AV_SYNC_VIDEO_MASTER;
3584 else if (!strcmp(arg, "ext"))
3585 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3587 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3593 static int opt_seek(void *optctx, const char *opt, const char *arg)
3595 start_time = parse_time_or_die(opt, arg, 1);
3599 static int opt_duration(void *optctx, const char *opt, const char *arg)
3601 duration = parse_time_or_die(opt, arg, 1);
3605 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3607 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3608 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3609 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3610 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3614 static void opt_input_file(void *optctx, const char *filename)
3616 if (input_filename) {
3617 av_log(NULL, AV_LOG_FATAL,
3618 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3619 filename, input_filename);
3622 if (!strcmp(filename, "-"))
3624 input_filename = filename;
3627 static int opt_codec(void *optctx, const char *opt, const char *arg)
3629 const char *spec = strchr(opt, ':');
3631 av_log(NULL, AV_LOG_ERROR,
3632 "No media specifier was specified in '%s' in option '%s'\n",
3634 return AVERROR(EINVAL);
3638 case 'a' : audio_codec_name = arg; break;
3639 case 's' : subtitle_codec_name = arg; break;
3640 case 'v' : video_codec_name = arg; break;
3642 av_log(NULL, AV_LOG_ERROR,
3643 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3644 return AVERROR(EINVAL);
3651 static const OptionDef options[] = {
3652 #include "cmdutils_common_opts.h"
3653 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3654 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3655 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3656 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3657 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3658 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3659 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3660 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3661 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3662 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3663 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3664 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3665 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3666 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3667 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3668 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3669 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3670 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3671 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3672 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3673 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3674 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3675 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3676 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3677 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3678 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3679 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3680 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3681 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3683 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3684 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3686 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3687 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3688 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3689 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3690 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3691 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3692 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3693 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3694 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3698 static void show_usage(void)
3700 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3701 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3702 av_log(NULL, AV_LOG_INFO, "\n");
3705 void show_help_default(const char *opt, const char *arg)
3707 av_log_set_callback(log_callback_help);
3709 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3710 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3712 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3713 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3714 #if !CONFIG_AVFILTER
3715 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3717 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3719 printf("\nWhile playing:\n"
3721 "f toggle full screen\n"
3724 "9, 0 decrease and increase volume respectively\n"
3725 "/, * decrease and increase volume respectively\n"
3726 "a cycle audio channel in the current program\n"
3727 "v cycle video channel\n"
3728 "t cycle subtitle channel in the current program\n"
3730 "w cycle video filters or show modes\n"
3731 "s activate frame-step mode\n"
3732 "left/right seek backward/forward 10 seconds\n"
3733 "down/up seek backward/forward 1 minute\n"
3734 "page down/page up seek backward/forward 10 minutes\n"
3735 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3736 "left double-click toggle full screen\n"
3740 static int lockmgr(void **mtx, enum AVLockOp op)
3743 case AV_LOCK_CREATE:
3744 *mtx = SDL_CreateMutex();
3746 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3750 case AV_LOCK_OBTAIN:
3751 return !!SDL_LockMutex(*mtx);
3752 case AV_LOCK_RELEASE:
3753 return !!SDL_UnlockMutex(*mtx);
3754 case AV_LOCK_DESTROY:
3755 SDL_DestroyMutex(*mtx);
3761 /* Called from the main */
3762 int main(int argc, char **argv)
3766 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3767 char alsa_bufsize[] = "SDL_AUDIO_ALSA_SET_BUFFER_SIZE=1";
3769 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3770 parse_loglevel(argc, argv, options);
3772 /* register all codecs, demux and protocols */
3774 avdevice_register_all();
3777 avfilter_register_all();
3780 avformat_network_init();
3784 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3785 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3787 show_banner(argc, argv, options);
3789 parse_options(NULL, argc, argv, options, opt_input_file);
3791 if (!input_filename) {
3793 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3794 av_log(NULL, AV_LOG_FATAL,
3795 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3799 if (display_disable) {
3802 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3804 flags &= ~SDL_INIT_AUDIO;
3806 /* Try to work around an occasional ALSA buffer underflow issue when the
3807 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3808 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3809 SDL_putenv(alsa_bufsize);
3811 if (display_disable)
3812 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3813 #if !defined(_WIN32) && !defined(__APPLE__)
3814 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3816 if (SDL_Init (flags)) {
3817 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3818 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3822 if (!display_disable) {
3823 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3824 fs_screen_width = vi->current_w;
3825 fs_screen_height = vi->current_h;
3828 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3829 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3830 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3832 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3834 if (av_lockmgr_register(lockmgr)) {
3835 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3839 av_init_packet(&flush_pkt);
3840 flush_pkt.data = (uint8_t *)&flush_pkt;
3842 is = stream_open(input_filename, file_iformat);
3844 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");