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 /* jump back to the previous frame if available by resetting rindex_shown */
773 static int frame_queue_prev(FrameQueue *f)
775 int ret = f->rindex_shown;
780 /* return the number of undisplayed frames in the queue */
781 static int frame_queue_nb_remaining(FrameQueue *f)
783 return f->size - f->rindex_shown;
786 /* return last shown position */
787 static int64_t frame_queue_last_pos(FrameQueue *f)
789 Frame *fp = &f->queue[f->rindex];
790 if (f->rindex_shown && fp->serial == f->pktq->serial)
796 static void decoder_abort(Decoder *d, FrameQueue *fq)
798 packet_queue_abort(d->queue);
799 frame_queue_signal(fq);
800 SDL_WaitThread(d->decoder_tid, NULL);
801 d->decoder_tid = NULL;
802 packet_queue_flush(d->queue);
805 static inline void fill_rectangle(SDL_Surface *screen,
806 int x, int y, int w, int h, int color, int update)
813 SDL_FillRect(screen, &rect, color);
814 if (update && w > 0 && h > 0)
815 SDL_UpdateRect(screen, x, y, w, h);
818 /* draw only the border of a rectangle */
819 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
823 /* fill the background */
827 w2 = width - (x + w);
833 h2 = height - (y + h);
836 fill_rectangle(screen,
840 fill_rectangle(screen,
841 xleft + width - w2, ytop,
844 fill_rectangle(screen,
848 fill_rectangle(screen,
849 xleft + w1, ytop + height - h2,
854 #define ALPHA_BLEND(a, oldp, newp, s)\
855 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
861 static void blend_subrect(uint8_t **data, int *linesize, const AVSubtitleRect *rect, int imgw, int imgh)
863 int x, y, Y, U, V, A;
864 uint8_t *lum, *cb, *cr;
865 int dstx, dsty, dstw, dsth;
866 const AVSubtitleRect *src = rect;
868 dstw = av_clip(rect->w, 0, imgw);
869 dsth = av_clip(rect->h, 0, imgh);
870 dstx = av_clip(rect->x, 0, imgw - dstw);
871 dsty = av_clip(rect->y, 0, imgh - dsth);
872 lum = data[0] + dstx + dsty * linesize[0];
873 cb = data[1] + dstx/2 + (dsty >> 1) * linesize[1];
874 cr = data[2] + dstx/2 + (dsty >> 1) * linesize[2];
876 for (y = 0; y<dsth; y++) {
877 for (x = 0; x<dstw; x++) {
878 Y = src->data[0][x + y*src->linesize[0]];
879 A = src->data[3][x + y*src->linesize[3]];
880 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
883 lum += linesize[0] - dstw;
886 for (y = 0; y<dsth/2; y++) {
887 for (x = 0; x<dstw/2; x++) {
888 U = src->data[1][x + y*src->linesize[1]];
889 V = src->data[2][x + y*src->linesize[2]];
890 A = src->data[3][2*x + 2*y *src->linesize[3]]
891 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
892 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
893 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
894 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
895 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
899 cb += linesize[1] - dstw/2;
900 cr += linesize[2] - dstw/2;
904 static void free_picture(Frame *vp)
907 SDL_FreeYUVOverlay(vp->bmp);
912 static void calculate_display_rect(SDL_Rect *rect,
913 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
914 int pic_width, int pic_height, AVRational pic_sar)
917 int width, height, x, y;
919 if (pic_sar.num == 0)
922 aspect_ratio = av_q2d(pic_sar);
924 if (aspect_ratio <= 0.0)
926 aspect_ratio *= (float)pic_width / (float)pic_height;
928 /* XXX: we suppose the screen has a 1.0 pixel ratio */
930 width = lrint(height * aspect_ratio) & ~1;
931 if (width > scr_width) {
933 height = lrint(width / aspect_ratio) & ~1;
935 x = (scr_width - width) / 2;
936 y = (scr_height - height) / 2;
937 rect->x = scr_xleft + x;
938 rect->y = scr_ytop + y;
939 rect->w = FFMAX(width, 1);
940 rect->h = FFMAX(height, 1);
943 static void video_image_display(VideoState *is)
950 vp = frame_queue_peek(&is->pictq);
952 if (is->subtitle_st) {
953 if (frame_queue_nb_remaining(&is->subpq) > 0) {
954 sp = frame_queue_peek(&is->subpq);
956 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
960 SDL_LockYUVOverlay (vp->bmp);
962 data[0] = vp->bmp->pixels[0];
963 data[1] = vp->bmp->pixels[2];
964 data[2] = vp->bmp->pixels[1];
966 linesize[0] = vp->bmp->pitches[0];
967 linesize[1] = vp->bmp->pitches[2];
968 linesize[2] = vp->bmp->pitches[1];
970 for (i = 0; i < sp->sub.num_rects; i++)
971 blend_subrect(data, linesize, sp->subrects[i],
972 vp->bmp->w, vp->bmp->h);
974 SDL_UnlockYUVOverlay (vp->bmp);
979 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
981 SDL_DisplayYUVOverlay(vp->bmp, &rect);
983 if (rect.x != is->last_display_rect.x || rect.y != is->last_display_rect.y || rect.w != is->last_display_rect.w || rect.h != is->last_display_rect.h || is->force_refresh) {
984 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
985 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
986 is->last_display_rect = rect;
991 static inline int compute_mod(int a, int b)
993 return a < 0 ? a%b + b : a%b;
996 static void video_audio_display(VideoState *s)
998 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
999 int ch, channels, h, h2, bgcolor, fgcolor;
1001 int rdft_bits, nb_freq;
1003 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1005 nb_freq = 1 << (rdft_bits - 1);
1007 /* compute display index : center on currently output samples */
1008 channels = s->audio_tgt.channels;
1009 nb_display_channels = channels;
1011 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1013 delay = s->audio_write_buf_size;
1016 /* to be more precise, we take into account the time spent since
1017 the last buffer computation */
1018 if (audio_callback_time) {
1019 time_diff = av_gettime_relative() - audio_callback_time;
1020 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1023 delay += 2 * data_used;
1024 if (delay < data_used)
1027 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1028 if (s->show_mode == SHOW_MODE_WAVES) {
1030 for (i = 0; i < 1000; i += channels) {
1031 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1032 int a = s->sample_array[idx];
1033 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1034 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1035 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1037 if (h < score && (b ^ c) < 0) {
1044 s->last_i_start = i_start;
1046 i_start = s->last_i_start;
1049 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1050 if (s->show_mode == SHOW_MODE_WAVES) {
1051 fill_rectangle(screen,
1052 s->xleft, s->ytop, s->width, s->height,
1055 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1057 /* total height for one channel */
1058 h = s->height / nb_display_channels;
1059 /* graph height / 2 */
1061 for (ch = 0; ch < nb_display_channels; ch++) {
1063 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1064 for (x = 0; x < s->width; x++) {
1065 y = (s->sample_array[i] * h2) >> 15;
1072 fill_rectangle(screen,
1073 s->xleft + x, ys, 1, y,
1076 if (i >= SAMPLE_ARRAY_SIZE)
1077 i -= SAMPLE_ARRAY_SIZE;
1081 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1083 for (ch = 1; ch < nb_display_channels; ch++) {
1084 y = s->ytop + ch * h;
1085 fill_rectangle(screen,
1086 s->xleft, y, s->width, 1,
1089 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1091 nb_display_channels= FFMIN(nb_display_channels, 2);
1092 if (rdft_bits != s->rdft_bits) {
1093 av_rdft_end(s->rdft);
1094 av_free(s->rdft_data);
1095 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1096 s->rdft_bits = rdft_bits;
1097 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1099 if (!s->rdft || !s->rdft_data){
1100 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1101 s->show_mode = SHOW_MODE_WAVES;
1104 for (ch = 0; ch < nb_display_channels; ch++) {
1105 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1107 for (x = 0; x < 2 * nb_freq; x++) {
1108 double w = (x-nb_freq) * (1.0 / nb_freq);
1109 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1111 if (i >= SAMPLE_ARRAY_SIZE)
1112 i -= SAMPLE_ARRAY_SIZE;
1114 av_rdft_calc(s->rdft, data[ch]);
1116 /* Least efficient way to do this, we should of course
1117 * directly access it but it is more than fast enough. */
1118 for (y = 0; y < s->height; y++) {
1119 double w = 1 / sqrt(nb_freq);
1120 int a = sqrt(w * hypot(data[0][2 * y + 0], data[0][2 * y + 1]));
1121 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1125 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1127 fill_rectangle(screen,
1128 s->xpos, s->height-y, 1, 1,
1132 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1135 if (s->xpos >= s->width)
1140 static void stream_component_close(VideoState *is, int stream_index)
1142 AVFormatContext *ic = is->ic;
1143 AVCodecParameters *codecpar;
1145 if (stream_index < 0 || stream_index >= ic->nb_streams)
1147 codecpar = ic->streams[stream_index]->codecpar;
1149 switch (codecpar->codec_type) {
1150 case AVMEDIA_TYPE_AUDIO:
1151 decoder_abort(&is->auddec, &is->sampq);
1153 decoder_destroy(&is->auddec);
1154 swr_free(&is->swr_ctx);
1155 av_freep(&is->audio_buf1);
1156 is->audio_buf1_size = 0;
1157 is->audio_buf = NULL;
1160 av_rdft_end(is->rdft);
1161 av_freep(&is->rdft_data);
1166 case AVMEDIA_TYPE_VIDEO:
1167 decoder_abort(&is->viddec, &is->pictq);
1168 decoder_destroy(&is->viddec);
1170 case AVMEDIA_TYPE_SUBTITLE:
1171 decoder_abort(&is->subdec, &is->subpq);
1172 decoder_destroy(&is->subdec);
1178 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1179 switch (codecpar->codec_type) {
1180 case AVMEDIA_TYPE_AUDIO:
1181 is->audio_st = NULL;
1182 is->audio_stream = -1;
1184 case AVMEDIA_TYPE_VIDEO:
1185 is->video_st = NULL;
1186 is->video_stream = -1;
1188 case AVMEDIA_TYPE_SUBTITLE:
1189 is->subtitle_st = NULL;
1190 is->subtitle_stream = -1;
1197 static void stream_close(VideoState *is)
1199 /* XXX: use a special url_shutdown call to abort parse cleanly */
1200 is->abort_request = 1;
1201 SDL_WaitThread(is->read_tid, NULL);
1203 /* close each stream */
1204 if (is->audio_stream >= 0)
1205 stream_component_close(is, is->audio_stream);
1206 if (is->video_stream >= 0)
1207 stream_component_close(is, is->video_stream);
1208 if (is->subtitle_stream >= 0)
1209 stream_component_close(is, is->subtitle_stream);
1211 avformat_close_input(&is->ic);
1213 packet_queue_destroy(&is->videoq);
1214 packet_queue_destroy(&is->audioq);
1215 packet_queue_destroy(&is->subtitleq);
1217 /* free all pictures */
1218 frame_queue_destory(&is->pictq);
1219 frame_queue_destory(&is->sampq);
1220 frame_queue_destory(&is->subpq);
1221 SDL_DestroyCond(is->continue_read_thread);
1222 #if !CONFIG_AVFILTER
1223 sws_freeContext(is->img_convert_ctx);
1225 sws_freeContext(is->sub_convert_ctx);
1226 av_free(is->filename);
1230 static void do_exit(VideoState *is)
1235 av_lockmgr_register(NULL);
1238 av_freep(&vfilters_list);
1240 avformat_network_deinit();
1244 av_log(NULL, AV_LOG_QUIET, "%s", "");
1248 static void sigterm_handler(int sig)
1253 static void set_default_window_size(int width, int height, AVRational sar)
1256 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1257 default_width = rect.w;
1258 default_height = rect.h;
1261 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1263 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1266 if (is_full_screen) flags |= SDL_FULLSCREEN;
1267 else flags |= SDL_RESIZABLE;
1269 if (vp && vp->width)
1270 set_default_window_size(vp->width, vp->height, vp->sar);
1272 if (is_full_screen && fs_screen_width) {
1273 w = fs_screen_width;
1274 h = fs_screen_height;
1275 } else if (!is_full_screen && screen_width) {
1282 w = FFMIN(16383, w);
1283 if (screen && is->width == screen->w && screen->w == w
1284 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1286 screen = SDL_SetVideoMode(w, h, 0, flags);
1288 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1292 window_title = input_filename;
1293 SDL_WM_SetCaption(window_title, window_title);
1295 is->width = screen->w;
1296 is->height = screen->h;
1301 /* display the current picture, if any */
1302 static void video_display(VideoState *is)
1305 video_open(is, 0, NULL);
1306 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1307 video_audio_display(is);
1308 else if (is->video_st)
1309 video_image_display(is);
1312 static double get_clock(Clock *c)
1314 if (*c->queue_serial != c->serial)
1319 double time = av_gettime_relative() / 1000000.0;
1320 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1324 static void set_clock_at(Clock *c, double pts, int serial, double time)
1327 c->last_updated = time;
1328 c->pts_drift = c->pts - time;
1332 static void set_clock(Clock *c, double pts, int serial)
1334 double time = av_gettime_relative() / 1000000.0;
1335 set_clock_at(c, pts, serial, time);
1338 static void set_clock_speed(Clock *c, double speed)
1340 set_clock(c, get_clock(c), c->serial);
1344 static void init_clock(Clock *c, int *queue_serial)
1348 c->queue_serial = queue_serial;
1349 set_clock(c, NAN, -1);
1352 static void sync_clock_to_slave(Clock *c, Clock *slave)
1354 double clock = get_clock(c);
1355 double slave_clock = get_clock(slave);
1356 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1357 set_clock(c, slave_clock, slave->serial);
1360 static int get_master_sync_type(VideoState *is) {
1361 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1363 return AV_SYNC_VIDEO_MASTER;
1365 return AV_SYNC_AUDIO_MASTER;
1366 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1368 return AV_SYNC_AUDIO_MASTER;
1370 return AV_SYNC_EXTERNAL_CLOCK;
1372 return AV_SYNC_EXTERNAL_CLOCK;
1376 /* get the current master clock value */
1377 static double get_master_clock(VideoState *is)
1381 switch (get_master_sync_type(is)) {
1382 case AV_SYNC_VIDEO_MASTER:
1383 val = get_clock(&is->vidclk);
1385 case AV_SYNC_AUDIO_MASTER:
1386 val = get_clock(&is->audclk);
1389 val = get_clock(&is->extclk);
1395 static void check_external_clock_speed(VideoState *is) {
1396 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1397 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1398 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1399 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1400 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1401 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1403 double speed = is->extclk.speed;
1405 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1409 /* seek in the stream */
1410 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1412 if (!is->seek_req) {
1415 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1417 is->seek_flags |= AVSEEK_FLAG_BYTE;
1419 SDL_CondSignal(is->continue_read_thread);
1423 /* pause or resume the video */
1424 static void stream_toggle_pause(VideoState *is)
1427 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1428 if (is->read_pause_return != AVERROR(ENOSYS)) {
1429 is->vidclk.paused = 0;
1431 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1433 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1434 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1437 static void toggle_pause(VideoState *is)
1439 stream_toggle_pause(is);
1443 static void toggle_mute(VideoState *is)
1445 is->muted = !is->muted;
1448 static void update_volume(VideoState *is, int sign, int step)
1450 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1453 static void step_to_next_frame(VideoState *is)
1455 /* if the stream is paused unpause it, then step */
1457 stream_toggle_pause(is);
1461 static double compute_target_delay(double delay, VideoState *is)
1463 double sync_threshold, diff = 0;
1465 /* update delay to follow master synchronisation source */
1466 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1467 /* if video is slave, we try to correct big delays by
1468 duplicating or deleting a frame */
1469 diff = get_clock(&is->vidclk) - get_master_clock(is);
1471 /* skip or repeat frame. We take into account the
1472 delay to compute the threshold. I still don't know
1473 if it is the best guess */
1474 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1475 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1476 if (diff <= -sync_threshold)
1477 delay = FFMAX(0, delay + diff);
1478 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1479 delay = delay + diff;
1480 else if (diff >= sync_threshold)
1485 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1491 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1492 if (vp->serial == nextvp->serial) {
1493 double duration = nextvp->pts - vp->pts;
1494 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1495 return vp->duration;
1503 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1504 /* update current video pts */
1505 set_clock(&is->vidclk, pts, serial);
1506 sync_clock_to_slave(&is->extclk, &is->vidclk);
1509 /* called to display each frame */
1510 static void video_refresh(void *opaque, double *remaining_time)
1512 VideoState *is = opaque;
1517 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1518 check_external_clock_speed(is);
1520 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1521 time = av_gettime_relative() / 1000000.0;
1522 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1524 is->last_vis_time = time;
1526 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1531 if (is->force_refresh)
1532 redisplay = frame_queue_prev(&is->pictq);
1534 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1535 // nothing to do, no picture to display in the queue
1537 double last_duration, duration, delay;
1540 /* dequeue the picture */
1541 lastvp = frame_queue_peek_last(&is->pictq);
1542 vp = frame_queue_peek(&is->pictq);
1544 if (vp->serial != is->videoq.serial) {
1545 frame_queue_next(&is->pictq);
1550 if (lastvp->serial != vp->serial && !redisplay)
1551 is->frame_timer = av_gettime_relative() / 1000000.0;
1556 /* compute nominal last_duration */
1557 last_duration = vp_duration(is, lastvp, vp);
1561 delay = compute_target_delay(last_duration, is);
1563 time= av_gettime_relative()/1000000.0;
1564 if (time < is->frame_timer + delay && !redisplay) {
1565 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1569 is->frame_timer += delay;
1570 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1571 is->frame_timer = time;
1573 SDL_LockMutex(is->pictq.mutex);
1574 if (!redisplay && !isnan(vp->pts))
1575 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1576 SDL_UnlockMutex(is->pictq.mutex);
1578 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1579 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1580 duration = vp_duration(is, vp, nextvp);
1581 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1583 is->frame_drops_late++;
1584 frame_queue_next(&is->pictq);
1590 if (is->subtitle_st) {
1591 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1592 sp = frame_queue_peek(&is->subpq);
1594 if (frame_queue_nb_remaining(&is->subpq) > 1)
1595 sp2 = frame_queue_peek_next(&is->subpq);
1599 if (sp->serial != is->subtitleq.serial
1600 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1601 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1603 frame_queue_next(&is->subpq);
1611 /* display picture */
1612 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1615 frame_queue_next(&is->pictq);
1617 if (is->step && !is->paused)
1618 stream_toggle_pause(is);
1621 is->force_refresh = 0;
1623 static int64_t last_time;
1625 int aqsize, vqsize, sqsize;
1628 cur_time = av_gettime_relative();
1629 if (!last_time || (cur_time - last_time) >= 30000) {
1634 aqsize = is->audioq.size;
1636 vqsize = is->videoq.size;
1637 if (is->subtitle_st)
1638 sqsize = is->subtitleq.size;
1640 if (is->audio_st && is->video_st)
1641 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1642 else if (is->video_st)
1643 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1644 else if (is->audio_st)
1645 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1646 av_log(NULL, AV_LOG_INFO,
1647 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1648 get_master_clock(is),
1649 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1651 is->frame_drops_early + is->frame_drops_late,
1655 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1656 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1658 last_time = cur_time;
1663 /* allocate a picture (needs to do that in main thread to avoid
1664 potential locking problems */
1665 static void alloc_picture(VideoState *is)
1670 vp = &is->pictq.queue[is->pictq.windex];
1674 video_open(is, 0, vp);
1676 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1679 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1680 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1681 /* SDL allocates a buffer smaller than requested if the video
1682 * overlay hardware is unable to support the requested size. */
1683 av_log(NULL, AV_LOG_FATAL,
1684 "Error: the video system does not support an image\n"
1685 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1686 "to reduce the image size.\n", vp->width, vp->height );
1690 SDL_LockMutex(is->pictq.mutex);
1692 SDL_CondSignal(is->pictq.cond);
1693 SDL_UnlockMutex(is->pictq.mutex);
1696 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1697 int i, width, height;
1699 for (i = 0; i < 3; i++) {
1706 if (bmp->pitches[i] > width) {
1707 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1708 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1714 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1718 #if defined(DEBUG_SYNC)
1719 printf("frame_type=%c pts=%0.3f\n",
1720 av_get_picture_type_char(src_frame->pict_type), pts);
1723 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1726 vp->sar = src_frame->sample_aspect_ratio;
1728 /* alloc or resize hardware picture buffer */
1729 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1730 vp->width != src_frame->width ||
1731 vp->height != src_frame->height) {
1736 vp->width = src_frame->width;
1737 vp->height = src_frame->height;
1739 /* the allocation must be done in the main thread to avoid
1740 locking problems. */
1741 event.type = FF_ALLOC_EVENT;
1742 event.user.data1 = is;
1743 SDL_PushEvent(&event);
1745 /* wait until the picture is allocated */
1746 SDL_LockMutex(is->pictq.mutex);
1747 while (!vp->allocated && !is->videoq.abort_request) {
1748 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1750 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1751 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1752 while (!vp->allocated && !is->abort_request) {
1753 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1756 SDL_UnlockMutex(is->pictq.mutex);
1758 if (is->videoq.abort_request)
1762 /* if the frame is not skipped, then display it */
1767 /* get a pointer on the bitmap */
1768 SDL_LockYUVOverlay (vp->bmp);
1770 data[0] = vp->bmp->pixels[0];
1771 data[1] = vp->bmp->pixels[2];
1772 data[2] = vp->bmp->pixels[1];
1774 linesize[0] = vp->bmp->pitches[0];
1775 linesize[1] = vp->bmp->pitches[2];
1776 linesize[2] = vp->bmp->pitches[1];
1779 // FIXME use direct rendering
1780 av_image_copy(data, linesize, (const uint8_t **)src_frame->data, src_frame->linesize,
1781 src_frame->format, vp->width, vp->height);
1784 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1786 const AVClass *class = sws_get_class();
1787 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1788 AV_OPT_SEARCH_FAKE_OBJ);
1789 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1795 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1796 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1797 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1798 if (!is->img_convert_ctx) {
1799 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1802 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1803 0, vp->height, data, linesize);
1805 /* workaround SDL PITCH_WORKAROUND */
1806 duplicate_right_border_pixels(vp->bmp);
1807 /* update the bitmap content */
1808 SDL_UnlockYUVOverlay(vp->bmp);
1811 vp->duration = duration;
1813 vp->serial = serial;
1815 /* now we can update the picture count */
1816 frame_queue_push(&is->pictq);
1821 static int get_video_frame(VideoState *is, AVFrame *frame)
1825 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1831 if (frame->pts != AV_NOPTS_VALUE)
1832 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1834 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1836 is->viddec_width = frame->width;
1837 is->viddec_height = frame->height;
1839 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1840 if (frame->pts != AV_NOPTS_VALUE) {
1841 double diff = dpts - get_master_clock(is);
1842 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1843 diff - is->frame_last_filter_delay < 0 &&
1844 is->viddec.pkt_serial == is->vidclk.serial &&
1845 is->videoq.nb_packets) {
1846 is->frame_drops_early++;
1847 av_frame_unref(frame);
1858 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1859 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1862 int nb_filters = graph->nb_filters;
1863 AVFilterInOut *outputs = NULL, *inputs = NULL;
1866 outputs = avfilter_inout_alloc();
1867 inputs = avfilter_inout_alloc();
1868 if (!outputs || !inputs) {
1869 ret = AVERROR(ENOMEM);
1873 outputs->name = av_strdup("in");
1874 outputs->filter_ctx = source_ctx;
1875 outputs->pad_idx = 0;
1876 outputs->next = NULL;
1878 inputs->name = av_strdup("out");
1879 inputs->filter_ctx = sink_ctx;
1880 inputs->pad_idx = 0;
1881 inputs->next = NULL;
1883 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1886 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1890 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1891 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1892 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1894 ret = avfilter_graph_config(graph, NULL);
1896 avfilter_inout_free(&outputs);
1897 avfilter_inout_free(&inputs);
1901 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1903 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1904 char sws_flags_str[512] = "";
1905 char buffersrc_args[256];
1907 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1908 AVCodecParameters *codecpar = is->video_st->codecpar;
1909 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1910 AVDictionaryEntry *e = NULL;
1912 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1913 if (!strcmp(e->key, "sws_flags")) {
1914 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1916 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1918 if (strlen(sws_flags_str))
1919 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1921 graph->scale_sws_opts = av_strdup(sws_flags_str);
1923 snprintf(buffersrc_args, sizeof(buffersrc_args),
1924 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1925 frame->width, frame->height, frame->format,
1926 is->video_st->time_base.num, is->video_st->time_base.den,
1927 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1928 if (fr.num && fr.den)
1929 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1931 if ((ret = avfilter_graph_create_filter(&filt_src,
1932 avfilter_get_by_name("buffer"),
1933 "ffplay_buffer", buffersrc_args, NULL,
1937 ret = avfilter_graph_create_filter(&filt_out,
1938 avfilter_get_by_name("buffersink"),
1939 "ffplay_buffersink", NULL, NULL, graph);
1943 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1946 last_filter = filt_out;
1948 /* Note: this macro adds a filter before the lastly added filter, so the
1949 * processing order of the filters is in reverse */
1950 #define INSERT_FILT(name, arg) do { \
1951 AVFilterContext *filt_ctx; \
1953 ret = avfilter_graph_create_filter(&filt_ctx, \
1954 avfilter_get_by_name(name), \
1955 "ffplay_" name, arg, NULL, graph); \
1959 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1963 last_filter = filt_ctx; \
1966 /* SDL YUV code is not handling odd width/height for some driver
1967 * combinations, therefore we crop the picture to an even width/height. */
1968 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1971 double theta = get_rotation(is->video_st);
1973 if (fabs(theta - 90) < 1.0) {
1974 INSERT_FILT("transpose", "clock");
1975 } else if (fabs(theta - 180) < 1.0) {
1976 INSERT_FILT("hflip", NULL);
1977 INSERT_FILT("vflip", NULL);
1978 } else if (fabs(theta - 270) < 1.0) {
1979 INSERT_FILT("transpose", "cclock");
1980 } else if (fabs(theta) > 1.0) {
1981 char rotate_buf[64];
1982 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1983 INSERT_FILT("rotate", rotate_buf);
1987 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1990 is->in_video_filter = filt_src;
1991 is->out_video_filter = filt_out;
1997 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1999 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2000 int sample_rates[2] = { 0, -1 };
2001 int64_t channel_layouts[2] = { 0, -1 };
2002 int channels[2] = { 0, -1 };
2003 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2004 char aresample_swr_opts[512] = "";
2005 AVDictionaryEntry *e = NULL;
2006 char asrc_args[256];
2009 avfilter_graph_free(&is->agraph);
2010 if (!(is->agraph = avfilter_graph_alloc()))
2011 return AVERROR(ENOMEM);
2013 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2014 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2015 if (strlen(aresample_swr_opts))
2016 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2017 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2019 ret = snprintf(asrc_args, sizeof(asrc_args),
2020 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2021 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2022 is->audio_filter_src.channels,
2023 1, is->audio_filter_src.freq);
2024 if (is->audio_filter_src.channel_layout)
2025 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2026 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2028 ret = avfilter_graph_create_filter(&filt_asrc,
2029 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2030 asrc_args, NULL, is->agraph);
2035 ret = avfilter_graph_create_filter(&filt_asink,
2036 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2037 NULL, NULL, is->agraph);
2041 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2043 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2046 if (force_output_format) {
2047 channel_layouts[0] = is->audio_tgt.channel_layout;
2048 channels [0] = is->audio_tgt.channels;
2049 sample_rates [0] = is->audio_tgt.freq;
2050 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2052 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2054 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2056 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2061 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2064 is->in_audio_filter = filt_asrc;
2065 is->out_audio_filter = filt_asink;
2069 avfilter_graph_free(&is->agraph);
2072 #endif /* CONFIG_AVFILTER */
2074 static int audio_thread(void *arg)
2076 VideoState *is = arg;
2077 AVFrame *frame = av_frame_alloc();
2080 int last_serial = -1;
2081 int64_t dec_channel_layout;
2089 return AVERROR(ENOMEM);
2092 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2096 tb = (AVRational){1, frame->sample_rate};
2099 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2102 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2103 frame->format, av_frame_get_channels(frame)) ||
2104 is->audio_filter_src.channel_layout != dec_channel_layout ||
2105 is->audio_filter_src.freq != frame->sample_rate ||
2106 is->auddec.pkt_serial != last_serial;
2109 char buf1[1024], buf2[1024];
2110 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2111 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2112 av_log(NULL, AV_LOG_DEBUG,
2113 "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
2114 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2115 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2117 is->audio_filter_src.fmt = frame->format;
2118 is->audio_filter_src.channels = av_frame_get_channels(frame);
2119 is->audio_filter_src.channel_layout = dec_channel_layout;
2120 is->audio_filter_src.freq = frame->sample_rate;
2121 last_serial = is->auddec.pkt_serial;
2123 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2127 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2130 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2131 tb = is->out_audio_filter->inputs[0]->time_base;
2133 if (!(af = frame_queue_peek_writable(&is->sampq)))
2136 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2137 af->pos = av_frame_get_pkt_pos(frame);
2138 af->serial = is->auddec.pkt_serial;
2139 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2141 av_frame_move_ref(af->frame, frame);
2142 frame_queue_push(&is->sampq);
2145 if (is->audioq.serial != is->auddec.pkt_serial)
2148 if (ret == AVERROR_EOF)
2149 is->auddec.finished = is->auddec.pkt_serial;
2152 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2155 avfilter_graph_free(&is->agraph);
2157 av_frame_free(&frame);
2161 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2163 packet_queue_start(d->queue);
2164 d->decoder_tid = SDL_CreateThread(fn, arg);
2165 if (!d->decoder_tid) {
2166 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2167 return AVERROR(ENOMEM);
2172 static int video_thread(void *arg)
2174 VideoState *is = arg;
2175 AVFrame *frame = av_frame_alloc();
2179 AVRational tb = is->video_st->time_base;
2180 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2183 AVFilterGraph *graph = avfilter_graph_alloc();
2184 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2187 enum AVPixelFormat last_format = -2;
2188 int last_serial = -1;
2189 int last_vfilter_idx = 0;
2191 av_frame_free(&frame);
2192 return AVERROR(ENOMEM);
2199 avfilter_graph_free(&graph);
2201 return AVERROR(ENOMEM);
2205 ret = get_video_frame(is, frame);
2212 if ( last_w != frame->width
2213 || last_h != frame->height
2214 || last_format != frame->format
2215 || last_serial != is->viddec.pkt_serial
2216 || last_vfilter_idx != is->vfilter_idx) {
2217 av_log(NULL, AV_LOG_DEBUG,
2218 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2220 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2221 frame->width, frame->height,
2222 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2223 avfilter_graph_free(&graph);
2224 graph = avfilter_graph_alloc();
2225 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2227 event.type = FF_QUIT_EVENT;
2228 event.user.data1 = is;
2229 SDL_PushEvent(&event);
2232 filt_in = is->in_video_filter;
2233 filt_out = is->out_video_filter;
2234 last_w = frame->width;
2235 last_h = frame->height;
2236 last_format = frame->format;
2237 last_serial = is->viddec.pkt_serial;
2238 last_vfilter_idx = is->vfilter_idx;
2239 frame_rate = filt_out->inputs[0]->frame_rate;
2242 ret = av_buffersrc_add_frame(filt_in, frame);
2247 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2249 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2251 if (ret == AVERROR_EOF)
2252 is->viddec.finished = is->viddec.pkt_serial;
2257 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2258 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2259 is->frame_last_filter_delay = 0;
2260 tb = filt_out->inputs[0]->time_base;
2262 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2263 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2264 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2265 av_frame_unref(frame);
2275 avfilter_graph_free(&graph);
2277 av_frame_free(&frame);
2281 static int subtitle_thread(void *arg)
2283 VideoState *is = arg;
2290 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2293 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2298 if (got_subtitle && sp->sub.format == 0) {
2299 if (sp->sub.pts != AV_NOPTS_VALUE)
2300 pts = sp->sub.pts / (double)AV_TIME_BASE;
2302 sp->serial = is->subdec.pkt_serial;
2303 if (!(sp->subrects = av_mallocz_array(sp->sub.num_rects, sizeof(AVSubtitleRect*)))) {
2304 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subrects\n");
2308 for (i = 0; i < sp->sub.num_rects; i++)
2310 int in_w = sp->sub.rects[i]->w;
2311 int in_h = sp->sub.rects[i]->h;
2312 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2313 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2314 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2315 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2317 if (!(sp->subrects[i] = av_mallocz(sizeof(AVSubtitleRect))) ||
2318 av_image_alloc(sp->subrects[i]->data, sp->subrects[i]->linesize, out_w, out_h, AV_PIX_FMT_YUVA420P, 16) < 0) {
2319 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subtitle data\n");
2323 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2324 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2325 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2326 if (!is->sub_convert_ctx) {
2327 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2330 sws_scale(is->sub_convert_ctx,
2331 (void*)sp->sub.rects[i]->data, sp->sub.rects[i]->linesize,
2332 0, in_h, sp->subrects[i]->data, sp->subrects[i]->linesize);
2334 sp->subrects[i]->w = out_w;
2335 sp->subrects[i]->h = out_h;
2336 sp->subrects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2337 sp->subrects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2340 /* now we can update the picture count */
2341 frame_queue_push(&is->subpq);
2342 } else if (got_subtitle) {
2343 avsubtitle_free(&sp->sub);
2349 /* copy samples for viewing in editor window */
2350 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2354 size = samples_size / sizeof(short);
2356 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2359 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2361 is->sample_array_index += len;
2362 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2363 is->sample_array_index = 0;
2368 /* return the wanted number of samples to get better sync if sync_type is video
2369 * or external master clock */
2370 static int synchronize_audio(VideoState *is, int nb_samples)
2372 int wanted_nb_samples = nb_samples;
2374 /* if not master, then we try to remove or add samples to correct the clock */
2375 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2376 double diff, avg_diff;
2377 int min_nb_samples, max_nb_samples;
2379 diff = get_clock(&is->audclk) - get_master_clock(is);
2381 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2382 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2383 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2384 /* not enough measures to have a correct estimate */
2385 is->audio_diff_avg_count++;
2387 /* estimate the A-V difference */
2388 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2390 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2391 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2392 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2393 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2394 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2396 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2397 diff, avg_diff, wanted_nb_samples - nb_samples,
2398 is->audio_clock, is->audio_diff_threshold);
2401 /* too big difference : may be initial PTS errors, so
2403 is->audio_diff_avg_count = 0;
2404 is->audio_diff_cum = 0;
2408 return wanted_nb_samples;
2412 * Decode one audio frame and return its uncompressed size.
2414 * The processed audio frame is decoded, converted if required, and
2415 * stored in is->audio_buf, with size in bytes given by the return
2418 static int audio_decode_frame(VideoState *is)
2420 int data_size, resampled_data_size;
2421 int64_t dec_channel_layout;
2422 av_unused double audio_clock0;
2423 int wanted_nb_samples;
2431 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2432 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2437 if (!(af = frame_queue_peek_readable(&is->sampq)))
2439 frame_queue_next(&is->sampq);
2440 } while (af->serial != is->audioq.serial);
2442 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2443 af->frame->nb_samples,
2444 af->frame->format, 1);
2446 dec_channel_layout =
2447 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2448 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2449 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2451 if (af->frame->format != is->audio_src.fmt ||
2452 dec_channel_layout != is->audio_src.channel_layout ||
2453 af->frame->sample_rate != is->audio_src.freq ||
2454 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2455 swr_free(&is->swr_ctx);
2456 is->swr_ctx = swr_alloc_set_opts(NULL,
2457 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2458 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2460 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2461 av_log(NULL, AV_LOG_ERROR,
2462 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2463 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2464 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2465 swr_free(&is->swr_ctx);
2468 is->audio_src.channel_layout = dec_channel_layout;
2469 is->audio_src.channels = av_frame_get_channels(af->frame);
2470 is->audio_src.freq = af->frame->sample_rate;
2471 is->audio_src.fmt = af->frame->format;
2475 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2476 uint8_t **out = &is->audio_buf1;
2477 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2478 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2481 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2484 if (wanted_nb_samples != af->frame->nb_samples) {
2485 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2486 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2487 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2491 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2492 if (!is->audio_buf1)
2493 return AVERROR(ENOMEM);
2494 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2496 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2499 if (len2 == out_count) {
2500 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2501 if (swr_init(is->swr_ctx) < 0)
2502 swr_free(&is->swr_ctx);
2504 is->audio_buf = is->audio_buf1;
2505 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2507 is->audio_buf = af->frame->data[0];
2508 resampled_data_size = data_size;
2511 audio_clock0 = is->audio_clock;
2512 /* update the audio clock with the pts */
2513 if (!isnan(af->pts))
2514 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2516 is->audio_clock = NAN;
2517 is->audio_clock_serial = af->serial;
2520 static double last_clock;
2521 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2522 is->audio_clock - last_clock,
2523 is->audio_clock, audio_clock0);
2524 last_clock = is->audio_clock;
2527 return resampled_data_size;
2530 /* prepare a new audio buffer */
2531 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2533 VideoState *is = opaque;
2534 int audio_size, len1;
2536 audio_callback_time = av_gettime_relative();
2539 if (is->audio_buf_index >= is->audio_buf_size) {
2540 audio_size = audio_decode_frame(is);
2541 if (audio_size < 0) {
2542 /* if error, just output silence */
2543 is->audio_buf = NULL;
2544 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2546 if (is->show_mode != SHOW_MODE_VIDEO)
2547 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2548 is->audio_buf_size = audio_size;
2550 is->audio_buf_index = 0;
2552 len1 = is->audio_buf_size - is->audio_buf_index;
2555 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2556 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2558 memset(stream, 0, len1);
2559 if (!is->muted && is->audio_buf)
2560 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2564 is->audio_buf_index += len1;
2566 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2567 /* Let's assume the audio driver that is used by SDL has two periods. */
2568 if (!isnan(is->audio_clock)) {
2569 set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
2570 sync_clock_to_slave(&is->extclk, &is->audclk);
2574 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2576 SDL_AudioSpec wanted_spec, spec;
2578 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2579 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2580 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2582 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2584 wanted_nb_channels = atoi(env);
2585 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2587 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2588 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2589 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2591 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2592 wanted_spec.channels = wanted_nb_channels;
2593 wanted_spec.freq = wanted_sample_rate;
2594 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2595 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2598 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2599 next_sample_rate_idx--;
2600 wanted_spec.format = AUDIO_S16SYS;
2601 wanted_spec.silence = 0;
2602 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2603 wanted_spec.callback = sdl_audio_callback;
2604 wanted_spec.userdata = opaque;
2605 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2606 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2607 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2608 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2609 if (!wanted_spec.channels) {
2610 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2611 wanted_spec.channels = wanted_nb_channels;
2612 if (!wanted_spec.freq) {
2613 av_log(NULL, AV_LOG_ERROR,
2614 "No more combinations to try, audio open failed\n");
2618 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2620 if (spec.format != AUDIO_S16SYS) {
2621 av_log(NULL, AV_LOG_ERROR,
2622 "SDL advised audio format %d is not supported!\n", spec.format);
2625 if (spec.channels != wanted_spec.channels) {
2626 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2627 if (!wanted_channel_layout) {
2628 av_log(NULL, AV_LOG_ERROR,
2629 "SDL advised channel count %d is not supported!\n", spec.channels);
2634 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2635 audio_hw_params->freq = spec.freq;
2636 audio_hw_params->channel_layout = wanted_channel_layout;
2637 audio_hw_params->channels = spec.channels;
2638 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2639 audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
2640 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2641 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2647 /* open a given stream. Return 0 if OK */
2648 static int stream_component_open(VideoState *is, int stream_index)
2650 AVFormatContext *ic = is->ic;
2651 AVCodecContext *avctx;
2653 const char *forced_codec_name = NULL;
2654 AVDictionary *opts = NULL;
2655 AVDictionaryEntry *t = NULL;
2656 int sample_rate, nb_channels;
2657 int64_t channel_layout;
2659 int stream_lowres = lowres;
2661 if (stream_index < 0 || stream_index >= ic->nb_streams)
2664 avctx = avcodec_alloc_context3(NULL);
2666 return AVERROR(ENOMEM);
2668 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2671 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2673 codec = avcodec_find_decoder(avctx->codec_id);
2675 switch(avctx->codec_type){
2676 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2677 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2678 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2680 if (forced_codec_name)
2681 codec = avcodec_find_decoder_by_name(forced_codec_name);
2683 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2684 "No codec could be found with name '%s'\n", forced_codec_name);
2685 else av_log(NULL, AV_LOG_WARNING,
2686 "No codec could be found with id %d\n", avctx->codec_id);
2687 ret = AVERROR(EINVAL);
2691 avctx->codec_id = codec->id;
2692 if(stream_lowres > av_codec_get_max_lowres(codec)){
2693 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2694 av_codec_get_max_lowres(codec));
2695 stream_lowres = av_codec_get_max_lowres(codec);
2697 av_codec_set_lowres(avctx, stream_lowres);
2700 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2703 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2705 if(codec->capabilities & AV_CODEC_CAP_DR1)
2706 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2709 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2710 if (!av_dict_get(opts, "threads", NULL, 0))
2711 av_dict_set(&opts, "threads", "auto", 0);
2713 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2714 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2715 av_dict_set(&opts, "refcounted_frames", "1", 0);
2716 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2719 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2720 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2721 ret = AVERROR_OPTION_NOT_FOUND;
2726 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2727 switch (avctx->codec_type) {
2728 case AVMEDIA_TYPE_AUDIO:
2733 is->audio_filter_src.freq = avctx->sample_rate;
2734 is->audio_filter_src.channels = avctx->channels;
2735 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2736 is->audio_filter_src.fmt = avctx->sample_fmt;
2737 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2739 link = is->out_audio_filter->inputs[0];
2740 sample_rate = link->sample_rate;
2741 nb_channels = link->channels;
2742 channel_layout = link->channel_layout;
2745 sample_rate = avctx->sample_rate;
2746 nb_channels = avctx->channels;
2747 channel_layout = avctx->channel_layout;
2750 /* prepare audio output */
2751 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2753 is->audio_hw_buf_size = ret;
2754 is->audio_src = is->audio_tgt;
2755 is->audio_buf_size = 0;
2756 is->audio_buf_index = 0;
2758 /* init averaging filter */
2759 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2760 is->audio_diff_avg_count = 0;
2761 /* since we do not have a precise anough audio fifo fullness,
2762 we correct audio sync only if larger than this threshold */
2763 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2765 is->audio_stream = stream_index;
2766 is->audio_st = ic->streams[stream_index];
2768 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2769 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2770 is->auddec.start_pts = is->audio_st->start_time;
2771 is->auddec.start_pts_tb = is->audio_st->time_base;
2773 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2777 case AVMEDIA_TYPE_VIDEO:
2778 is->video_stream = stream_index;
2779 is->video_st = ic->streams[stream_index];
2781 is->viddec_width = avctx->width;
2782 is->viddec_height = avctx->height;
2784 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2785 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2787 is->queue_attachments_req = 1;
2789 case AVMEDIA_TYPE_SUBTITLE:
2790 is->subtitle_stream = stream_index;
2791 is->subtitle_st = ic->streams[stream_index];
2793 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2794 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2803 avcodec_free_context(&avctx);
2805 av_dict_free(&opts);
2810 static int decode_interrupt_cb(void *ctx)
2812 VideoState *is = ctx;
2813 return is->abort_request;
2816 static int is_realtime(AVFormatContext *s)
2818 if( !strcmp(s->iformat->name, "rtp")
2819 || !strcmp(s->iformat->name, "rtsp")
2820 || !strcmp(s->iformat->name, "sdp")
2824 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2825 || !strncmp(s->filename, "udp:", 4)
2832 /* this thread gets the stream from the disk or the network */
2833 static int read_thread(void *arg)
2835 VideoState *is = arg;
2836 AVFormatContext *ic = NULL;
2838 int st_index[AVMEDIA_TYPE_NB];
2839 AVPacket pkt1, *pkt = &pkt1;
2840 int64_t stream_start_time;
2841 int pkt_in_play_range = 0;
2842 AVDictionaryEntry *t;
2843 AVDictionary **opts;
2844 int orig_nb_streams;
2845 SDL_mutex *wait_mutex = SDL_CreateMutex();
2846 int scan_all_pmts_set = 0;
2850 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2851 ret = AVERROR(ENOMEM);
2855 memset(st_index, -1, sizeof(st_index));
2856 is->last_video_stream = is->video_stream = -1;
2857 is->last_audio_stream = is->audio_stream = -1;
2858 is->last_subtitle_stream = is->subtitle_stream = -1;
2861 ic = avformat_alloc_context();
2863 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2864 ret = AVERROR(ENOMEM);
2867 ic->interrupt_callback.callback = decode_interrupt_cb;
2868 ic->interrupt_callback.opaque = is;
2869 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2870 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2871 scan_all_pmts_set = 1;
2873 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2875 print_error(is->filename, err);
2879 if (scan_all_pmts_set)
2880 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2882 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2883 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2884 ret = AVERROR_OPTION_NOT_FOUND;
2890 ic->flags |= AVFMT_FLAG_GENPTS;
2892 av_format_inject_global_side_data(ic);
2894 opts = setup_find_stream_info_opts(ic, codec_opts);
2895 orig_nb_streams = ic->nb_streams;
2897 err = avformat_find_stream_info(ic, opts);
2899 for (i = 0; i < orig_nb_streams; i++)
2900 av_dict_free(&opts[i]);
2904 av_log(NULL, AV_LOG_WARNING,
2905 "%s: could not find codec parameters\n", is->filename);
2911 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2913 if (seek_by_bytes < 0)
2914 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2916 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2918 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2919 window_title = av_asprintf("%s - %s", t->value, input_filename);
2921 /* if seeking requested, we execute it */
2922 if (start_time != AV_NOPTS_VALUE) {
2925 timestamp = start_time;
2926 /* add the stream start time */
2927 if (ic->start_time != AV_NOPTS_VALUE)
2928 timestamp += ic->start_time;
2929 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2931 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2932 is->filename, (double)timestamp / AV_TIME_BASE);
2936 is->realtime = is_realtime(ic);
2939 av_dump_format(ic, 0, is->filename, 0);
2941 for (i = 0; i < ic->nb_streams; i++) {
2942 AVStream *st = ic->streams[i];
2943 enum AVMediaType type = st->codecpar->codec_type;
2944 st->discard = AVDISCARD_ALL;
2945 if (wanted_stream_spec[type] && st_index[type] == -1)
2946 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2949 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2950 if (wanted_stream_spec[i] && st_index[i] == -1) {
2951 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));
2952 st_index[i] = INT_MAX;
2957 st_index[AVMEDIA_TYPE_VIDEO] =
2958 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2959 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2961 st_index[AVMEDIA_TYPE_AUDIO] =
2962 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2963 st_index[AVMEDIA_TYPE_AUDIO],
2964 st_index[AVMEDIA_TYPE_VIDEO],
2966 if (!video_disable && !subtitle_disable)
2967 st_index[AVMEDIA_TYPE_SUBTITLE] =
2968 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2969 st_index[AVMEDIA_TYPE_SUBTITLE],
2970 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2971 st_index[AVMEDIA_TYPE_AUDIO] :
2972 st_index[AVMEDIA_TYPE_VIDEO]),
2975 is->show_mode = show_mode;
2976 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2977 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2978 AVCodecParameters *codecpar = st->codecpar;
2979 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2980 if (codecpar->width)
2981 set_default_window_size(codecpar->width, codecpar->height, sar);
2984 /* open the streams */
2985 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2986 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2990 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2991 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2993 if (is->show_mode == SHOW_MODE_NONE)
2994 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2996 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2997 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
3000 if (is->video_stream < 0 && is->audio_stream < 0) {
3001 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
3007 if (infinite_buffer < 0 && is->realtime)
3008 infinite_buffer = 1;
3011 if (is->abort_request)
3013 if (is->paused != is->last_paused) {
3014 is->last_paused = is->paused;
3016 is->read_pause_return = av_read_pause(ic);
3020 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3022 (!strcmp(ic->iformat->name, "rtsp") ||
3023 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3024 /* wait 10 ms to avoid trying to get another packet */
3031 int64_t seek_target = is->seek_pos;
3032 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3033 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3034 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3035 // of the seek_pos/seek_rel variables
3037 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3039 av_log(NULL, AV_LOG_ERROR,
3040 "%s: error while seeking\n", is->ic->filename);
3042 if (is->audio_stream >= 0) {
3043 packet_queue_flush(&is->audioq);
3044 packet_queue_put(&is->audioq, &flush_pkt);
3046 if (is->subtitle_stream >= 0) {
3047 packet_queue_flush(&is->subtitleq);
3048 packet_queue_put(&is->subtitleq, &flush_pkt);
3050 if (is->video_stream >= 0) {
3051 packet_queue_flush(&is->videoq);
3052 packet_queue_put(&is->videoq, &flush_pkt);
3054 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3055 set_clock(&is->extclk, NAN, 0);
3057 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3061 is->queue_attachments_req = 1;
3064 step_to_next_frame(is);
3066 if (is->queue_attachments_req) {
3067 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3069 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3071 packet_queue_put(&is->videoq, ©);
3072 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3074 is->queue_attachments_req = 0;
3077 /* if the queue are full, no need to read more */
3078 if (infinite_buffer<1 &&
3079 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3080 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3081 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3082 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3083 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3085 SDL_LockMutex(wait_mutex);
3086 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3087 SDL_UnlockMutex(wait_mutex);
3091 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3092 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3093 if (loop != 1 && (!loop || --loop)) {
3094 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3095 } else if (autoexit) {
3100 ret = av_read_frame(ic, pkt);
3102 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3103 if (is->video_stream >= 0)
3104 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3105 if (is->audio_stream >= 0)
3106 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3107 if (is->subtitle_stream >= 0)
3108 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3111 if (ic->pb && ic->pb->error)
3113 SDL_LockMutex(wait_mutex);
3114 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3115 SDL_UnlockMutex(wait_mutex);
3120 /* check if packet is in play range specified by user, then queue, otherwise discard */
3121 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3122 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3123 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3124 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3125 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3126 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3127 <= ((double)duration / 1000000);
3128 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3129 packet_queue_put(&is->audioq, pkt);
3130 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3131 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3132 packet_queue_put(&is->videoq, pkt);
3133 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3134 packet_queue_put(&is->subtitleq, pkt);
3136 av_packet_unref(pkt);
3143 avformat_close_input(&ic);
3148 event.type = FF_QUIT_EVENT;
3149 event.user.data1 = is;
3150 SDL_PushEvent(&event);
3152 SDL_DestroyMutex(wait_mutex);
3156 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3160 is = av_mallocz(sizeof(VideoState));
3163 is->filename = av_strdup(filename);
3166 is->iformat = iformat;
3170 /* start video display */
3171 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3173 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3175 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3178 if (packet_queue_init(&is->videoq) < 0 ||
3179 packet_queue_init(&is->audioq) < 0 ||
3180 packet_queue_init(&is->subtitleq) < 0)
3183 if (!(is->continue_read_thread = SDL_CreateCond())) {
3184 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3188 init_clock(&is->vidclk, &is->videoq.serial);
3189 init_clock(&is->audclk, &is->audioq.serial);
3190 init_clock(&is->extclk, &is->extclk.serial);
3191 is->audio_clock_serial = -1;
3192 is->audio_volume = SDL_MIX_MAXVOLUME;
3194 is->av_sync_type = av_sync_type;
3195 is->read_tid = SDL_CreateThread(read_thread, is);
3196 if (!is->read_tid) {
3197 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3205 static void stream_cycle_channel(VideoState *is, int codec_type)
3207 AVFormatContext *ic = is->ic;
3208 int start_index, stream_index;
3211 AVProgram *p = NULL;
3212 int nb_streams = is->ic->nb_streams;
3214 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3215 start_index = is->last_video_stream;
3216 old_index = is->video_stream;
3217 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3218 start_index = is->last_audio_stream;
3219 old_index = is->audio_stream;
3221 start_index = is->last_subtitle_stream;
3222 old_index = is->subtitle_stream;
3224 stream_index = start_index;
3226 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3227 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3229 nb_streams = p->nb_stream_indexes;
3230 for (start_index = 0; start_index < nb_streams; start_index++)
3231 if (p->stream_index[start_index] == stream_index)
3233 if (start_index == nb_streams)
3235 stream_index = start_index;
3240 if (++stream_index >= nb_streams)
3242 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3245 is->last_subtitle_stream = -1;
3248 if (start_index == -1)
3252 if (stream_index == start_index)
3254 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3255 if (st->codecpar->codec_type == codec_type) {
3256 /* check that parameters are OK */
3257 switch (codec_type) {
3258 case AVMEDIA_TYPE_AUDIO:
3259 if (st->codecpar->sample_rate != 0 &&
3260 st->codecpar->channels != 0)
3263 case AVMEDIA_TYPE_VIDEO:
3264 case AVMEDIA_TYPE_SUBTITLE:
3272 if (p && stream_index != -1)
3273 stream_index = p->stream_index[stream_index];
3274 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3275 av_get_media_type_string(codec_type),
3279 stream_component_close(is, old_index);
3280 stream_component_open(is, stream_index);
3284 static void toggle_full_screen(VideoState *is)
3286 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3287 /* OS X needs to reallocate the SDL overlays */
3289 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3290 is->pictq.queue[i].reallocate = 1;
3292 is_full_screen = !is_full_screen;
3293 video_open(is, 1, NULL);
3296 static void toggle_audio_display(VideoState *is)
3298 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3299 int next = is->show_mode;
3301 next = (next + 1) % SHOW_MODE_NB;
3302 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3303 if (is->show_mode != next) {
3304 fill_rectangle(screen,
3305 is->xleft, is->ytop, is->width, is->height,
3307 is->force_refresh = 1;
3308 is->show_mode = next;
3312 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3313 double remaining_time = 0.0;
3315 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3316 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3320 if (remaining_time > 0.0)
3321 av_usleep((int64_t)(remaining_time * 1000000.0));
3322 remaining_time = REFRESH_RATE;
3323 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3324 video_refresh(is, &remaining_time);
3329 static void seek_chapter(VideoState *is, int incr)
3331 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3334 if (!is->ic->nb_chapters)
3337 /* find the current chapter */
3338 for (i = 0; i < is->ic->nb_chapters; i++) {
3339 AVChapter *ch = is->ic->chapters[i];
3340 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3348 if (i >= is->ic->nb_chapters)
3351 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3352 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3353 AV_TIME_BASE_Q), 0, 0);
3356 /* handle an event sent by the GUI */
3357 static void event_loop(VideoState *cur_stream)
3360 double incr, pos, frac;
3364 refresh_loop_wait_event(cur_stream, &event);
3365 switch (event.type) {
3367 if (exit_on_keydown) {
3368 do_exit(cur_stream);
3371 switch (event.key.keysym.sym) {
3374 do_exit(cur_stream);
3377 toggle_full_screen(cur_stream);
3378 cur_stream->force_refresh = 1;
3382 toggle_pause(cur_stream);
3385 toggle_mute(cur_stream);
3387 case SDLK_KP_MULTIPLY:
3389 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3391 case SDLK_KP_DIVIDE:
3393 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3395 case SDLK_s: // S: Step to next frame
3396 step_to_next_frame(cur_stream);
3399 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3402 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3405 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3406 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3407 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3410 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3414 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3415 if (++cur_stream->vfilter_idx >= nb_vfilters)
3416 cur_stream->vfilter_idx = 0;
3418 cur_stream->vfilter_idx = 0;
3419 toggle_audio_display(cur_stream);
3422 toggle_audio_display(cur_stream);
3426 if (cur_stream->ic->nb_chapters <= 1) {
3430 seek_chapter(cur_stream, 1);
3433 if (cur_stream->ic->nb_chapters <= 1) {
3437 seek_chapter(cur_stream, -1);
3451 if (seek_by_bytes) {
3453 if (pos < 0 && cur_stream->video_stream >= 0)
3454 pos = frame_queue_last_pos(&cur_stream->pictq);
3455 if (pos < 0 && cur_stream->audio_stream >= 0)
3456 pos = frame_queue_last_pos(&cur_stream->sampq);
3458 pos = avio_tell(cur_stream->ic->pb);
3459 if (cur_stream->ic->bit_rate)
3460 incr *= cur_stream->ic->bit_rate / 8.0;
3464 stream_seek(cur_stream, pos, incr, 1);
3466 pos = get_master_clock(cur_stream);
3468 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3470 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3471 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3472 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3479 case SDL_VIDEOEXPOSE:
3480 cur_stream->force_refresh = 1;
3482 case SDL_MOUSEBUTTONDOWN:
3483 if (exit_on_mousedown) {
3484 do_exit(cur_stream);
3487 if (event.button.button == SDL_BUTTON_LEFT) {
3488 static int64_t last_mouse_left_click = 0;
3489 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3490 toggle_full_screen(cur_stream);
3491 cur_stream->force_refresh = 1;
3492 last_mouse_left_click = 0;
3494 last_mouse_left_click = av_gettime_relative();
3497 case SDL_MOUSEMOTION:
3498 if (cursor_hidden) {
3502 cursor_last_shown = av_gettime_relative();
3503 if (event.type == SDL_MOUSEBUTTONDOWN) {
3504 if (event.button.button != SDL_BUTTON_RIGHT)
3508 if (!(event.motion.state & SDL_BUTTON_RMASK))
3512 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3513 uint64_t size = avio_size(cur_stream->ic->pb);
3514 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3518 int tns, thh, tmm, tss;
3519 tns = cur_stream->ic->duration / 1000000LL;
3521 tmm = (tns % 3600) / 60;
3523 frac = x / cur_stream->width;
3526 mm = (ns % 3600) / 60;
3528 av_log(NULL, AV_LOG_INFO,
3529 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3530 hh, mm, ss, thh, tmm, tss);
3531 ts = frac * cur_stream->ic->duration;
3532 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3533 ts += cur_stream->ic->start_time;
3534 stream_seek(cur_stream, ts, 0, 0);
3537 case SDL_VIDEORESIZE:
3538 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3539 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3541 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3542 do_exit(cur_stream);
3544 screen_width = cur_stream->width = screen->w;
3545 screen_height = cur_stream->height = screen->h;
3546 cur_stream->force_refresh = 1;
3550 do_exit(cur_stream);
3552 case FF_ALLOC_EVENT:
3553 alloc_picture(event.user.data1);
3561 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3563 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3564 return opt_default(NULL, "video_size", arg);
3567 static int opt_width(void *optctx, const char *opt, const char *arg)
3569 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3573 static int opt_height(void *optctx, const char *opt, const char *arg)
3575 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3579 static int opt_format(void *optctx, const char *opt, const char *arg)
3581 file_iformat = av_find_input_format(arg);
3582 if (!file_iformat) {
3583 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3584 return AVERROR(EINVAL);
3589 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3591 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3592 return opt_default(NULL, "pixel_format", arg);
3595 static int opt_sync(void *optctx, const char *opt, const char *arg)
3597 if (!strcmp(arg, "audio"))
3598 av_sync_type = AV_SYNC_AUDIO_MASTER;
3599 else if (!strcmp(arg, "video"))
3600 av_sync_type = AV_SYNC_VIDEO_MASTER;
3601 else if (!strcmp(arg, "ext"))
3602 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3604 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3610 static int opt_seek(void *optctx, const char *opt, const char *arg)
3612 start_time = parse_time_or_die(opt, arg, 1);
3616 static int opt_duration(void *optctx, const char *opt, const char *arg)
3618 duration = parse_time_or_die(opt, arg, 1);
3622 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3624 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3625 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3626 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3627 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3631 static void opt_input_file(void *optctx, const char *filename)
3633 if (input_filename) {
3634 av_log(NULL, AV_LOG_FATAL,
3635 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3636 filename, input_filename);
3639 if (!strcmp(filename, "-"))
3641 input_filename = filename;
3644 static int opt_codec(void *optctx, const char *opt, const char *arg)
3646 const char *spec = strchr(opt, ':');
3648 av_log(NULL, AV_LOG_ERROR,
3649 "No media specifier was specified in '%s' in option '%s'\n",
3651 return AVERROR(EINVAL);
3655 case 'a' : audio_codec_name = arg; break;
3656 case 's' : subtitle_codec_name = arg; break;
3657 case 'v' : video_codec_name = arg; break;
3659 av_log(NULL, AV_LOG_ERROR,
3660 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3661 return AVERROR(EINVAL);
3668 static const OptionDef options[] = {
3669 #include "cmdutils_common_opts.h"
3670 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3671 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3672 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3673 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3674 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3675 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3676 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3677 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3678 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3679 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3680 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3681 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3682 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3683 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3684 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3685 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3686 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3687 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3688 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3689 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3690 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3691 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3692 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3693 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3694 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3695 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3696 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3697 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3698 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3700 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3701 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3703 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3704 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3705 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3706 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3707 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3708 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3709 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3710 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3711 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3715 static void show_usage(void)
3717 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3718 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3719 av_log(NULL, AV_LOG_INFO, "\n");
3722 void show_help_default(const char *opt, const char *arg)
3724 av_log_set_callback(log_callback_help);
3726 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3727 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3729 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3730 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3731 #if !CONFIG_AVFILTER
3732 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3734 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3736 printf("\nWhile playing:\n"
3738 "f toggle full screen\n"
3741 "9, 0 decrease and increase volume respectively\n"
3742 "/, * decrease and increase volume respectively\n"
3743 "a cycle audio channel in the current program\n"
3744 "v cycle video channel\n"
3745 "t cycle subtitle channel in the current program\n"
3747 "w cycle video filters or show modes\n"
3748 "s activate frame-step mode\n"
3749 "left/right seek backward/forward 10 seconds\n"
3750 "down/up seek backward/forward 1 minute\n"
3751 "page down/page up seek backward/forward 10 minutes\n"
3752 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3753 "left double-click toggle full screen\n"
3757 static int lockmgr(void **mtx, enum AVLockOp op)
3760 case AV_LOCK_CREATE:
3761 *mtx = SDL_CreateMutex();
3763 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3767 case AV_LOCK_OBTAIN:
3768 return !!SDL_LockMutex(*mtx);
3769 case AV_LOCK_RELEASE:
3770 return !!SDL_UnlockMutex(*mtx);
3771 case AV_LOCK_DESTROY:
3772 SDL_DestroyMutex(*mtx);
3778 /* Called from the main */
3779 int main(int argc, char **argv)
3783 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3785 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3786 parse_loglevel(argc, argv, options);
3788 /* register all codecs, demux and protocols */
3790 avdevice_register_all();
3793 avfilter_register_all();
3796 avformat_network_init();
3800 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3801 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3803 show_banner(argc, argv, options);
3805 parse_options(NULL, argc, argv, options, opt_input_file);
3807 if (!input_filename) {
3809 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3810 av_log(NULL, AV_LOG_FATAL,
3811 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3815 if (display_disable) {
3818 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3820 flags &= ~SDL_INIT_AUDIO;
3821 if (display_disable)
3822 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3823 #if !defined(_WIN32) && !defined(__APPLE__)
3824 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3826 if (SDL_Init (flags)) {
3827 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3828 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3832 if (!display_disable) {
3833 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3834 fs_screen_width = vi->current_w;
3835 fs_screen_height = vi->current_h;
3838 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3839 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3840 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3842 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3844 if (av_lockmgr_register(lockmgr)) {
3845 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3849 av_init_packet(&flush_pkt);
3850 flush_pkt.data = (uint8_t *)&flush_pkt;
3852 is = stream_open(input_filename, file_iformat);
3854 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");