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/colorspace.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/avcodec.h"
52 # include "libavfilter/avfilter.h"
53 # include "libavfilter/buffersink.h"
54 # include "libavfilter/buffersrc.h"
58 #include <SDL_thread.h>
64 const char program_name[] = "ffplay";
65 const int program_birth_year = 2003;
67 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
70 /* Minimum SDL audio buffer size, in samples. */
71 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
72 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
73 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
75 /* no AV sync correction is done if below the minimum AV sync threshold */
76 #define AV_SYNC_THRESHOLD_MIN 0.04
77 /* AV sync correction is done if above the maximum AV sync threshold */
78 #define AV_SYNC_THRESHOLD_MAX 0.1
79 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
80 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
81 /* no AV correction is done if too big error */
82 #define AV_NOSYNC_THRESHOLD 10.0
84 /* maximum audio speed change to get correct sync */
85 #define SAMPLE_CORRECTION_PERCENT_MAX 10
87 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
88 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
89 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
90 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
92 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
93 #define AUDIO_DIFF_AVG_NB 20
95 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
96 #define REFRESH_RATE 0.01
98 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
99 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
100 #define SAMPLE_ARRAY_SIZE (8 * 65536)
102 #define CURSOR_HIDE_DELAY 1000000
104 static int64_t sws_flags = SWS_BICUBIC;
106 typedef struct MyAVPacketList {
108 struct MyAVPacketList *next;
112 typedef struct PacketQueue {
113 MyAVPacketList *first_pkt, *last_pkt;
122 #define VIDEO_PICTURE_QUEUE_SIZE 3
123 #define SUBPICTURE_QUEUE_SIZE 16
124 #define SAMPLE_QUEUE_SIZE 9
125 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
127 typedef struct AudioParams {
130 int64_t channel_layout;
131 enum AVSampleFormat fmt;
136 typedef struct Clock {
137 double pts; /* clock base */
138 double pts_drift; /* clock base minus time at which we updated the clock */
141 int serial; /* clock is based on a packet with this serial */
143 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
146 /* Common struct for handling all types of decoded data and allocated render buffers. */
147 typedef struct Frame {
151 double pts; /* presentation timestamp for the frame */
152 double duration; /* estimated duration of the frame */
153 int64_t pos; /* byte position of the frame in the input file */
162 typedef struct FrameQueue {
163 Frame queue[FRAME_QUEUE_SIZE];
176 AV_SYNC_AUDIO_MASTER, /* default choice */
177 AV_SYNC_VIDEO_MASTER,
178 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
181 typedef struct Decoder {
185 AVCodecContext *avctx;
189 SDL_cond *empty_queue_cond;
191 AVRational start_pts_tb;
193 AVRational next_pts_tb;
196 typedef struct VideoState {
197 SDL_Thread *read_tid;
198 SDL_Thread *video_tid;
199 SDL_Thread *audio_tid;
200 AVInputFormat *iformat;
205 int queue_attachments_req;
210 int read_pause_return;
231 int audio_clock_serial;
232 double audio_diff_cum; /* used for AV difference average computation */
233 double audio_diff_avg_coef;
234 double audio_diff_threshold;
235 int audio_diff_avg_count;
238 int audio_hw_buf_size;
239 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
242 unsigned int audio_buf_size; /* in bytes */
243 unsigned int audio_buf1_size;
244 int audio_buf_index; /* in bytes */
245 int audio_write_buf_size;
246 struct AudioParams audio_src;
248 struct AudioParams audio_filter_src;
250 struct AudioParams audio_tgt;
251 struct SwrContext *swr_ctx;
252 int frame_drops_early;
253 int frame_drops_late;
256 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
258 int16_t sample_array[SAMPLE_ARRAY_SIZE];
259 int sample_array_index;
263 FFTSample *rdft_data;
265 double last_vis_time;
267 SDL_Thread *subtitle_tid;
269 AVStream *subtitle_st;
270 PacketQueue subtitleq;
273 double frame_last_returned_time;
274 double frame_last_filter_delay;
278 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
280 struct SwsContext *img_convert_ctx;
282 SDL_Rect last_display_rect;
285 int width, height, xleft, ytop;
290 AVFilterContext *in_video_filter; // the first filter in the video chain
291 AVFilterContext *out_video_filter; // the last filter in the video chain
292 AVFilterContext *in_audio_filter; // the first filter in the audio chain
293 AVFilterContext *out_audio_filter; // the last filter in the audio chain
294 AVFilterGraph *agraph; // audio filter graph
297 int last_video_stream, last_audio_stream, last_subtitle_stream;
299 SDL_cond *continue_read_thread;
302 /* options specified by the user */
303 static AVInputFormat *file_iformat;
304 static const char *input_filename;
305 static const char *window_title;
306 static int fs_screen_width;
307 static int fs_screen_height;
308 static int default_width = 640;
309 static int default_height = 480;
310 static int screen_width = 0;
311 static int screen_height = 0;
312 static int audio_disable;
313 static int video_disable;
314 static int subtitle_disable;
315 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
316 static int seek_by_bytes = -1;
317 static int display_disable;
318 static int show_status = 1;
319 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
320 static int64_t start_time = AV_NOPTS_VALUE;
321 static int64_t duration = AV_NOPTS_VALUE;
323 static int genpts = 0;
324 static int lowres = 0;
325 static int decoder_reorder_pts = -1;
327 static int exit_on_keydown;
328 static int exit_on_mousedown;
330 static int framedrop = -1;
331 static int infinite_buffer = -1;
332 static enum ShowMode show_mode = SHOW_MODE_NONE;
333 static const char *audio_codec_name;
334 static const char *subtitle_codec_name;
335 static const char *video_codec_name;
336 double rdftspeed = 0.02;
337 static int64_t cursor_last_shown;
338 static int cursor_hidden = 0;
340 static const char **vfilters_list = NULL;
341 static int nb_vfilters = 0;
342 static char *afilters = NULL;
344 static int autorotate = 1;
346 /* current context */
347 static int is_full_screen;
348 static int64_t audio_callback_time;
350 static AVPacket flush_pkt;
352 #define FF_ALLOC_EVENT (SDL_USEREVENT)
353 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
355 static SDL_Surface *screen;
358 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
360 GROW_ARRAY(vfilters_list, nb_vfilters);
361 vfilters_list[nb_vfilters - 1] = arg;
367 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
368 enum AVSampleFormat fmt2, int64_t channel_count2)
370 /* If channel count == 1, planar and non-planar formats are the same */
371 if (channel_count1 == 1 && channel_count2 == 1)
372 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
374 return channel_count1 != channel_count2 || fmt1 != fmt2;
378 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
380 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
381 return channel_layout;
386 static void free_picture(Frame *vp);
388 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
390 MyAVPacketList *pkt1;
392 if (q->abort_request)
395 pkt1 = av_malloc(sizeof(MyAVPacketList));
400 if (pkt == &flush_pkt)
402 pkt1->serial = q->serial;
407 q->last_pkt->next = pkt1;
410 q->size += pkt1->pkt.size + sizeof(*pkt1);
411 /* XXX: should duplicate packet data in DV case */
412 SDL_CondSignal(q->cond);
416 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
420 /* duplicate the packet */
421 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
424 SDL_LockMutex(q->mutex);
425 ret = packet_queue_put_private(q, pkt);
426 SDL_UnlockMutex(q->mutex);
428 if (pkt != &flush_pkt && ret < 0)
434 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
436 AVPacket pkt1, *pkt = &pkt1;
440 pkt->stream_index = stream_index;
441 return packet_queue_put(q, pkt);
444 /* packet queue handling */
445 static void packet_queue_init(PacketQueue *q)
447 memset(q, 0, sizeof(PacketQueue));
448 q->mutex = SDL_CreateMutex();
449 q->cond = SDL_CreateCond();
450 q->abort_request = 1;
453 static void packet_queue_flush(PacketQueue *q)
455 MyAVPacketList *pkt, *pkt1;
457 SDL_LockMutex(q->mutex);
458 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
460 av_free_packet(&pkt->pkt);
467 SDL_UnlockMutex(q->mutex);
470 static void packet_queue_destroy(PacketQueue *q)
472 packet_queue_flush(q);
473 SDL_DestroyMutex(q->mutex);
474 SDL_DestroyCond(q->cond);
477 static void packet_queue_abort(PacketQueue *q)
479 SDL_LockMutex(q->mutex);
481 q->abort_request = 1;
483 SDL_CondSignal(q->cond);
485 SDL_UnlockMutex(q->mutex);
488 static void packet_queue_start(PacketQueue *q)
490 SDL_LockMutex(q->mutex);
491 q->abort_request = 0;
492 packet_queue_put_private(q, &flush_pkt);
493 SDL_UnlockMutex(q->mutex);
496 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
497 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
499 MyAVPacketList *pkt1;
502 SDL_LockMutex(q->mutex);
505 if (q->abort_request) {
512 q->first_pkt = pkt1->next;
516 q->size -= pkt1->pkt.size + sizeof(*pkt1);
519 *serial = pkt1->serial;
527 SDL_CondWait(q->cond, q->mutex);
530 SDL_UnlockMutex(q->mutex);
534 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
535 memset(d, 0, sizeof(Decoder));
538 d->empty_queue_cond = empty_queue_cond;
539 d->start_pts = AV_NOPTS_VALUE;
542 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
548 if (d->queue->abort_request)
551 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
554 if (d->queue->nb_packets == 0)
555 SDL_CondSignal(d->empty_queue_cond);
556 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
558 if (pkt.data == flush_pkt.data) {
559 avcodec_flush_buffers(d->avctx);
561 d->next_pts = d->start_pts;
562 d->next_pts_tb = d->start_pts_tb;
564 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
565 av_free_packet(&d->pkt);
566 d->pkt_temp = d->pkt = pkt;
567 d->packet_pending = 1;
570 switch (d->avctx->codec_type) {
571 case AVMEDIA_TYPE_VIDEO:
572 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
574 if (decoder_reorder_pts == -1) {
575 frame->pts = av_frame_get_best_effort_timestamp(frame);
576 } else if (decoder_reorder_pts) {
577 frame->pts = frame->pkt_pts;
579 frame->pts = frame->pkt_dts;
583 case AVMEDIA_TYPE_AUDIO:
584 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
586 AVRational tb = (AVRational){1, frame->sample_rate};
587 if (frame->pts != AV_NOPTS_VALUE)
588 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
589 else if (frame->pkt_pts != AV_NOPTS_VALUE)
590 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
591 else if (d->next_pts != AV_NOPTS_VALUE)
592 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
593 if (frame->pts != AV_NOPTS_VALUE) {
594 d->next_pts = frame->pts + frame->nb_samples;
599 case AVMEDIA_TYPE_SUBTITLE:
600 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
605 d->packet_pending = 0;
608 d->pkt_temp.pts = AV_NOPTS_VALUE;
609 if (d->pkt_temp.data) {
610 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
611 ret = d->pkt_temp.size;
612 d->pkt_temp.data += ret;
613 d->pkt_temp.size -= ret;
614 if (d->pkt_temp.size <= 0)
615 d->packet_pending = 0;
618 d->packet_pending = 0;
619 d->finished = d->pkt_serial;
623 } while (!got_frame && !d->finished);
628 static void decoder_destroy(Decoder *d) {
629 av_free_packet(&d->pkt);
632 static void frame_queue_unref_item(Frame *vp)
634 av_frame_unref(vp->frame);
635 avsubtitle_free(&vp->sub);
638 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
641 memset(f, 0, sizeof(FrameQueue));
642 if (!(f->mutex = SDL_CreateMutex()))
643 return AVERROR(ENOMEM);
644 if (!(f->cond = SDL_CreateCond()))
645 return AVERROR(ENOMEM);
647 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
648 f->keep_last = !!keep_last;
649 for (i = 0; i < f->max_size; i++)
650 if (!(f->queue[i].frame = av_frame_alloc()))
651 return AVERROR(ENOMEM);
655 static void frame_queue_destory(FrameQueue *f)
658 for (i = 0; i < f->max_size; i++) {
659 Frame *vp = &f->queue[i];
660 frame_queue_unref_item(vp);
661 av_frame_free(&vp->frame);
664 SDL_DestroyMutex(f->mutex);
665 SDL_DestroyCond(f->cond);
668 static void frame_queue_signal(FrameQueue *f)
670 SDL_LockMutex(f->mutex);
671 SDL_CondSignal(f->cond);
672 SDL_UnlockMutex(f->mutex);
675 static Frame *frame_queue_peek(FrameQueue *f)
677 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
680 static Frame *frame_queue_peek_next(FrameQueue *f)
682 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
685 static Frame *frame_queue_peek_last(FrameQueue *f)
687 return &f->queue[f->rindex];
690 static Frame *frame_queue_peek_writable(FrameQueue *f)
692 /* wait until we have space to put a new frame */
693 SDL_LockMutex(f->mutex);
694 while (f->size >= f->max_size &&
695 !f->pktq->abort_request) {
696 SDL_CondWait(f->cond, f->mutex);
698 SDL_UnlockMutex(f->mutex);
700 if (f->pktq->abort_request)
703 return &f->queue[f->windex];
706 static Frame *frame_queue_peek_readable(FrameQueue *f)
708 /* wait until we have a readable a new frame */
709 SDL_LockMutex(f->mutex);
710 while (f->size - f->rindex_shown <= 0 &&
711 !f->pktq->abort_request) {
712 SDL_CondWait(f->cond, f->mutex);
714 SDL_UnlockMutex(f->mutex);
716 if (f->pktq->abort_request)
719 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
722 static void frame_queue_push(FrameQueue *f)
724 if (++f->windex == f->max_size)
726 SDL_LockMutex(f->mutex);
728 SDL_CondSignal(f->cond);
729 SDL_UnlockMutex(f->mutex);
732 static void frame_queue_next(FrameQueue *f)
734 if (f->keep_last && !f->rindex_shown) {
738 frame_queue_unref_item(&f->queue[f->rindex]);
739 if (++f->rindex == f->max_size)
741 SDL_LockMutex(f->mutex);
743 SDL_CondSignal(f->cond);
744 SDL_UnlockMutex(f->mutex);
747 /* jump back to the previous frame if available by resetting rindex_shown */
748 static int frame_queue_prev(FrameQueue *f)
750 int ret = f->rindex_shown;
755 /* return the number of undisplayed frames in the queue */
756 static int frame_queue_nb_remaining(FrameQueue *f)
758 return f->size - f->rindex_shown;
761 /* return last shown position */
762 static int64_t frame_queue_last_pos(FrameQueue *f)
764 Frame *fp = &f->queue[f->rindex];
765 if (f->rindex_shown && fp->serial == f->pktq->serial)
771 static inline void fill_rectangle(SDL_Surface *screen,
772 int x, int y, int w, int h, int color, int update)
779 SDL_FillRect(screen, &rect, color);
780 if (update && w > 0 && h > 0)
781 SDL_UpdateRect(screen, x, y, w, h);
784 /* draw only the border of a rectangle */
785 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
789 /* fill the background */
793 w2 = width - (x + w);
799 h2 = height - (y + h);
802 fill_rectangle(screen,
806 fill_rectangle(screen,
807 xleft + width - w2, ytop,
810 fill_rectangle(screen,
814 fill_rectangle(screen,
815 xleft + w1, ytop + height - h2,
820 #define ALPHA_BLEND(a, oldp, newp, s)\
821 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
823 #define RGBA_IN(r, g, b, a, s)\
825 unsigned int v = ((const uint32_t *)(s))[0];\
826 a = (v >> 24) & 0xff;\
827 r = (v >> 16) & 0xff;\
828 g = (v >> 8) & 0xff;\
832 #define YUVA_IN(y, u, v, a, s, pal)\
834 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
835 a = (val >> 24) & 0xff;\
836 y = (val >> 16) & 0xff;\
837 u = (val >> 8) & 0xff;\
841 #define YUVA_OUT(d, y, u, v, a)\
843 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
849 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
851 int wrap, wrap3, width2, skip2;
852 int y, u, v, a, u1, v1, a1, w, h;
853 uint8_t *lum, *cb, *cr;
856 int dstx, dsty, dstw, dsth;
858 dstw = av_clip(rect->w, 0, imgw);
859 dsth = av_clip(rect->h, 0, imgh);
860 dstx = av_clip(rect->x, 0, imgw - dstw);
861 dsty = av_clip(rect->y, 0, imgh - dsth);
862 lum = dst->data[0] + dsty * dst->linesize[0];
863 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
864 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
866 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
868 wrap = dst->linesize[0];
869 wrap3 = rect->pict.linesize[0];
870 p = rect->pict.data[0];
871 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
879 YUVA_IN(y, u, v, a, p, pal);
880 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
881 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
882 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
888 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
889 YUVA_IN(y, u, v, a, p, pal);
893 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
895 YUVA_IN(y, u, v, a, p + BPP, pal);
899 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
900 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
901 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
908 YUVA_IN(y, u, v, a, p, pal);
909 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
910 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
911 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
915 p += wrap3 - dstw * BPP;
916 lum += wrap - dstw - dstx;
917 cb += dst->linesize[1] - width2 - skip2;
918 cr += dst->linesize[2] - width2 - skip2;
920 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
926 YUVA_IN(y, u, v, a, p, pal);
930 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
933 YUVA_IN(y, u, v, a, p, pal);
937 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
938 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
939 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
945 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
946 YUVA_IN(y, u, v, a, p, pal);
950 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
952 YUVA_IN(y, u, v, a, p + BPP, pal);
956 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
960 YUVA_IN(y, u, v, a, p, pal);
964 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
966 YUVA_IN(y, u, v, a, p + BPP, pal);
970 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
972 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
973 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
977 p += -wrap3 + 2 * BPP;
981 YUVA_IN(y, u, v, a, p, pal);
985 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
988 YUVA_IN(y, u, v, a, p, pal);
992 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
993 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
994 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
1000 p += wrap3 + (wrap3 - dstw * BPP);
1001 lum += wrap + (wrap - dstw - dstx);
1002 cb += dst->linesize[1] - width2 - skip2;
1003 cr += dst->linesize[2] - width2 - skip2;
1005 /* handle odd height */
1012 YUVA_IN(y, u, v, a, p, pal);
1013 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1014 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1015 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1021 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
1022 YUVA_IN(y, u, v, a, p, pal);
1026 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1028 YUVA_IN(y, u, v, a, p + BPP, pal);
1032 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
1033 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
1034 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
1041 YUVA_IN(y, u, v, a, p, pal);
1042 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1043 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1044 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1049 static void free_picture(Frame *vp)
1052 SDL_FreeYUVOverlay(vp->bmp);
1057 static void calculate_display_rect(SDL_Rect *rect,
1058 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
1059 int pic_width, int pic_height, AVRational pic_sar)
1062 int width, height, x, y;
1064 if (pic_sar.num == 0)
1067 aspect_ratio = av_q2d(pic_sar);
1069 if (aspect_ratio <= 0.0)
1071 aspect_ratio *= (float)pic_width / (float)pic_height;
1073 /* XXX: we suppose the screen has a 1.0 pixel ratio */
1074 height = scr_height;
1075 width = ((int)rint(height * aspect_ratio)) & ~1;
1076 if (width > scr_width) {
1078 height = ((int)rint(width / aspect_ratio)) & ~1;
1080 x = (scr_width - width) / 2;
1081 y = (scr_height - height) / 2;
1082 rect->x = scr_xleft + x;
1083 rect->y = scr_ytop + y;
1084 rect->w = FFMAX(width, 1);
1085 rect->h = FFMAX(height, 1);
1088 static void video_image_display(VideoState *is)
1096 vp = frame_queue_peek(&is->pictq);
1098 if (is->subtitle_st) {
1099 if (frame_queue_nb_remaining(&is->subpq) > 0) {
1100 sp = frame_queue_peek(&is->subpq);
1102 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
1103 SDL_LockYUVOverlay (vp->bmp);
1105 pict.data[0] = vp->bmp->pixels[0];
1106 pict.data[1] = vp->bmp->pixels[2];
1107 pict.data[2] = vp->bmp->pixels[1];
1109 pict.linesize[0] = vp->bmp->pitches[0];
1110 pict.linesize[1] = vp->bmp->pitches[2];
1111 pict.linesize[2] = vp->bmp->pitches[1];
1113 for (i = 0; i < sp->sub.num_rects; i++)
1114 blend_subrect(&pict, sp->sub.rects[i],
1115 vp->bmp->w, vp->bmp->h);
1117 SDL_UnlockYUVOverlay (vp->bmp);
1122 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1124 SDL_DisplayYUVOverlay(vp->bmp, &rect);
1126 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) {
1127 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1128 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
1129 is->last_display_rect = rect;
1134 static inline int compute_mod(int a, int b)
1136 return a < 0 ? a%b + b : a%b;
1139 static void video_audio_display(VideoState *s)
1141 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1142 int ch, channels, h, h2, bgcolor, fgcolor;
1144 int rdft_bits, nb_freq;
1146 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1148 nb_freq = 1 << (rdft_bits - 1);
1150 /* compute display index : center on currently output samples */
1151 channels = s->audio_tgt.channels;
1152 nb_display_channels = channels;
1154 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1156 delay = s->audio_write_buf_size;
1159 /* to be more precise, we take into account the time spent since
1160 the last buffer computation */
1161 if (audio_callback_time) {
1162 time_diff = av_gettime_relative() - audio_callback_time;
1163 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1166 delay += 2 * data_used;
1167 if (delay < data_used)
1170 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1171 if (s->show_mode == SHOW_MODE_WAVES) {
1173 for (i = 0; i < 1000; i += channels) {
1174 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1175 int a = s->sample_array[idx];
1176 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1177 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1178 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1180 if (h < score && (b ^ c) < 0) {
1187 s->last_i_start = i_start;
1189 i_start = s->last_i_start;
1192 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1193 if (s->show_mode == SHOW_MODE_WAVES) {
1194 fill_rectangle(screen,
1195 s->xleft, s->ytop, s->width, s->height,
1198 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1200 /* total height for one channel */
1201 h = s->height / nb_display_channels;
1202 /* graph height / 2 */
1204 for (ch = 0; ch < nb_display_channels; ch++) {
1206 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1207 for (x = 0; x < s->width; x++) {
1208 y = (s->sample_array[i] * h2) >> 15;
1215 fill_rectangle(screen,
1216 s->xleft + x, ys, 1, y,
1219 if (i >= SAMPLE_ARRAY_SIZE)
1220 i -= SAMPLE_ARRAY_SIZE;
1224 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1226 for (ch = 1; ch < nb_display_channels; ch++) {
1227 y = s->ytop + ch * h;
1228 fill_rectangle(screen,
1229 s->xleft, y, s->width, 1,
1232 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1234 nb_display_channels= FFMIN(nb_display_channels, 2);
1235 if (rdft_bits != s->rdft_bits) {
1236 av_rdft_end(s->rdft);
1237 av_free(s->rdft_data);
1238 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1239 s->rdft_bits = rdft_bits;
1240 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1244 for (ch = 0; ch < nb_display_channels; ch++) {
1245 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1247 for (x = 0; x < 2 * nb_freq; x++) {
1248 double w = (x-nb_freq) * (1.0 / nb_freq);
1249 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1251 if (i >= SAMPLE_ARRAY_SIZE)
1252 i -= SAMPLE_ARRAY_SIZE;
1254 av_rdft_calc(s->rdft, data[ch]);
1256 /* Least efficient way to do this, we should of course
1257 * directly access it but it is more than fast enough. */
1258 for (y = 0; y < s->height; y++) {
1259 double w = 1 / sqrt(nb_freq);
1260 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
1261 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1262 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1265 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1267 fill_rectangle(screen,
1268 s->xpos, s->height-y, 1, 1,
1272 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1275 if (s->xpos >= s->width)
1280 static void stream_close(VideoState *is)
1282 /* XXX: use a special url_shutdown call to abort parse cleanly */
1283 is->abort_request = 1;
1284 SDL_WaitThread(is->read_tid, NULL);
1285 packet_queue_destroy(&is->videoq);
1286 packet_queue_destroy(&is->audioq);
1287 packet_queue_destroy(&is->subtitleq);
1289 /* free all pictures */
1290 frame_queue_destory(&is->pictq);
1291 frame_queue_destory(&is->sampq);
1292 frame_queue_destory(&is->subpq);
1293 SDL_DestroyCond(is->continue_read_thread);
1294 #if !CONFIG_AVFILTER
1295 sws_freeContext(is->img_convert_ctx);
1300 static void do_exit(VideoState *is)
1305 av_lockmgr_register(NULL);
1308 av_freep(&vfilters_list);
1310 avformat_network_deinit();
1314 av_log(NULL, AV_LOG_QUIET, "%s", "");
1318 static void sigterm_handler(int sig)
1323 static void set_default_window_size(int width, int height, AVRational sar)
1326 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1327 default_width = rect.w;
1328 default_height = rect.h;
1331 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1333 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1336 if (is_full_screen) flags |= SDL_FULLSCREEN;
1337 else flags |= SDL_RESIZABLE;
1339 if (vp && vp->width)
1340 set_default_window_size(vp->width, vp->height, vp->sar);
1342 if (is_full_screen && fs_screen_width) {
1343 w = fs_screen_width;
1344 h = fs_screen_height;
1345 } else if (!is_full_screen && screen_width) {
1352 w = FFMIN(16383, w);
1353 if (screen && is->width == screen->w && screen->w == w
1354 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1356 screen = SDL_SetVideoMode(w, h, 0, flags);
1358 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1362 window_title = input_filename;
1363 SDL_WM_SetCaption(window_title, window_title);
1365 is->width = screen->w;
1366 is->height = screen->h;
1371 /* display the current picture, if any */
1372 static void video_display(VideoState *is)
1375 video_open(is, 0, NULL);
1376 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1377 video_audio_display(is);
1378 else if (is->video_st)
1379 video_image_display(is);
1382 static double get_clock(Clock *c)
1384 if (*c->queue_serial != c->serial)
1389 double time = av_gettime_relative() / 1000000.0;
1390 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1394 static void set_clock_at(Clock *c, double pts, int serial, double time)
1397 c->last_updated = time;
1398 c->pts_drift = c->pts - time;
1402 static void set_clock(Clock *c, double pts, int serial)
1404 double time = av_gettime_relative() / 1000000.0;
1405 set_clock_at(c, pts, serial, time);
1408 static void set_clock_speed(Clock *c, double speed)
1410 set_clock(c, get_clock(c), c->serial);
1414 static void init_clock(Clock *c, int *queue_serial)
1418 c->queue_serial = queue_serial;
1419 set_clock(c, NAN, -1);
1422 static void sync_clock_to_slave(Clock *c, Clock *slave)
1424 double clock = get_clock(c);
1425 double slave_clock = get_clock(slave);
1426 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1427 set_clock(c, slave_clock, slave->serial);
1430 static int get_master_sync_type(VideoState *is) {
1431 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1433 return AV_SYNC_VIDEO_MASTER;
1435 return AV_SYNC_AUDIO_MASTER;
1436 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1438 return AV_SYNC_AUDIO_MASTER;
1440 return AV_SYNC_EXTERNAL_CLOCK;
1442 return AV_SYNC_EXTERNAL_CLOCK;
1446 /* get the current master clock value */
1447 static double get_master_clock(VideoState *is)
1451 switch (get_master_sync_type(is)) {
1452 case AV_SYNC_VIDEO_MASTER:
1453 val = get_clock(&is->vidclk);
1455 case AV_SYNC_AUDIO_MASTER:
1456 val = get_clock(&is->audclk);
1459 val = get_clock(&is->extclk);
1465 static void check_external_clock_speed(VideoState *is) {
1466 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1467 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1468 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1469 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1470 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1471 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1473 double speed = is->extclk.speed;
1475 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1479 /* seek in the stream */
1480 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1482 if (!is->seek_req) {
1485 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1487 is->seek_flags |= AVSEEK_FLAG_BYTE;
1489 SDL_CondSignal(is->continue_read_thread);
1493 /* pause or resume the video */
1494 static void stream_toggle_pause(VideoState *is)
1497 is->frame_timer += av_gettime_relative() / 1000000.0 + is->vidclk.pts_drift - is->vidclk.pts;
1498 if (is->read_pause_return != AVERROR(ENOSYS)) {
1499 is->vidclk.paused = 0;
1501 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1503 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1504 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1507 static void toggle_pause(VideoState *is)
1509 stream_toggle_pause(is);
1513 static void step_to_next_frame(VideoState *is)
1515 /* if the stream is paused unpause it, then step */
1517 stream_toggle_pause(is);
1521 static double compute_target_delay(double delay, VideoState *is)
1523 double sync_threshold, diff;
1525 /* update delay to follow master synchronisation source */
1526 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1527 /* if video is slave, we try to correct big delays by
1528 duplicating or deleting a frame */
1529 diff = get_clock(&is->vidclk) - get_master_clock(is);
1531 /* skip or repeat frame. We take into account the
1532 delay to compute the threshold. I still don't know
1533 if it is the best guess */
1534 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1535 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1536 if (diff <= -sync_threshold)
1537 delay = FFMAX(0, delay + diff);
1538 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1539 delay = delay + diff;
1540 else if (diff >= sync_threshold)
1545 av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1551 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1552 if (vp->serial == nextvp->serial) {
1553 double duration = nextvp->pts - vp->pts;
1554 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1555 return vp->duration;
1563 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1564 /* update current video pts */
1565 set_clock(&is->vidclk, pts, serial);
1566 sync_clock_to_slave(&is->extclk, &is->vidclk);
1569 /* called to display each frame */
1570 static void video_refresh(void *opaque, double *remaining_time)
1572 VideoState *is = opaque;
1577 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1578 check_external_clock_speed(is);
1580 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1581 time = av_gettime_relative() / 1000000.0;
1582 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1584 is->last_vis_time = time;
1586 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1591 if (is->force_refresh)
1592 redisplay = frame_queue_prev(&is->pictq);
1594 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1595 // nothing to do, no picture to display in the queue
1597 double last_duration, duration, delay;
1600 /* dequeue the picture */
1601 lastvp = frame_queue_peek_last(&is->pictq);
1602 vp = frame_queue_peek(&is->pictq);
1604 if (vp->serial != is->videoq.serial) {
1605 frame_queue_next(&is->pictq);
1610 if (lastvp->serial != vp->serial && !redisplay)
1611 is->frame_timer = av_gettime_relative() / 1000000.0;
1616 /* compute nominal last_duration */
1617 last_duration = vp_duration(is, lastvp, vp);
1621 delay = compute_target_delay(last_duration, is);
1623 time= av_gettime_relative()/1000000.0;
1624 if (time < is->frame_timer + delay && !redisplay) {
1625 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1629 is->frame_timer += delay;
1630 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1631 is->frame_timer = time;
1633 SDL_LockMutex(is->pictq.mutex);
1634 if (!redisplay && !isnan(vp->pts))
1635 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1636 SDL_UnlockMutex(is->pictq.mutex);
1638 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1639 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1640 duration = vp_duration(is, vp, nextvp);
1641 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1643 is->frame_drops_late++;
1644 frame_queue_next(&is->pictq);
1650 if (is->subtitle_st) {
1651 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1652 sp = frame_queue_peek(&is->subpq);
1654 if (frame_queue_nb_remaining(&is->subpq) > 1)
1655 sp2 = frame_queue_peek_next(&is->subpq);
1659 if (sp->serial != is->subtitleq.serial
1660 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1661 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1663 frame_queue_next(&is->subpq);
1671 /* display picture */
1672 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1675 frame_queue_next(&is->pictq);
1677 if (is->step && !is->paused)
1678 stream_toggle_pause(is);
1681 is->force_refresh = 0;
1683 static int64_t last_time;
1685 int aqsize, vqsize, sqsize;
1688 cur_time = av_gettime_relative();
1689 if (!last_time || (cur_time - last_time) >= 30000) {
1694 aqsize = is->audioq.size;
1696 vqsize = is->videoq.size;
1697 if (is->subtitle_st)
1698 sqsize = is->subtitleq.size;
1700 if (is->audio_st && is->video_st)
1701 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1702 else if (is->video_st)
1703 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1704 else if (is->audio_st)
1705 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1706 av_log(NULL, AV_LOG_INFO,
1707 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1708 get_master_clock(is),
1709 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1711 is->frame_drops_early + is->frame_drops_late,
1715 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1716 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1718 last_time = cur_time;
1723 /* allocate a picture (needs to do that in main thread to avoid
1724 potential locking problems */
1725 static void alloc_picture(VideoState *is)
1730 vp = &is->pictq.queue[is->pictq.windex];
1734 video_open(is, 0, vp);
1736 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1739 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1740 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1741 /* SDL allocates a buffer smaller than requested if the video
1742 * overlay hardware is unable to support the requested size. */
1743 av_log(NULL, AV_LOG_FATAL,
1744 "Error: the video system does not support an image\n"
1745 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1746 "to reduce the image size.\n", vp->width, vp->height );
1750 SDL_LockMutex(is->pictq.mutex);
1752 SDL_CondSignal(is->pictq.cond);
1753 SDL_UnlockMutex(is->pictq.mutex);
1756 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1757 int i, width, height;
1759 for (i = 0; i < 3; i++) {
1766 if (bmp->pitches[i] > width) {
1767 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1768 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1774 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1778 #if defined(DEBUG_SYNC) && 0
1779 printf("frame_type=%c pts=%0.3f\n",
1780 av_get_picture_type_char(src_frame->pict_type), pts);
1783 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1786 vp->sar = src_frame->sample_aspect_ratio;
1788 /* alloc or resize hardware picture buffer */
1789 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1790 vp->width != src_frame->width ||
1791 vp->height != src_frame->height) {
1796 vp->width = src_frame->width;
1797 vp->height = src_frame->height;
1799 /* the allocation must be done in the main thread to avoid
1800 locking problems. */
1801 event.type = FF_ALLOC_EVENT;
1802 event.user.data1 = is;
1803 SDL_PushEvent(&event);
1805 /* wait until the picture is allocated */
1806 SDL_LockMutex(is->pictq.mutex);
1807 while (!vp->allocated && !is->videoq.abort_request) {
1808 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1810 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1811 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1812 while (!vp->allocated && !is->abort_request) {
1813 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1816 SDL_UnlockMutex(is->pictq.mutex);
1818 if (is->videoq.abort_request)
1822 /* if the frame is not skipped, then display it */
1824 AVPicture pict = { { 0 } };
1826 /* get a pointer on the bitmap */
1827 SDL_LockYUVOverlay (vp->bmp);
1829 pict.data[0] = vp->bmp->pixels[0];
1830 pict.data[1] = vp->bmp->pixels[2];
1831 pict.data[2] = vp->bmp->pixels[1];
1833 pict.linesize[0] = vp->bmp->pitches[0];
1834 pict.linesize[1] = vp->bmp->pitches[2];
1835 pict.linesize[2] = vp->bmp->pitches[1];
1838 // FIXME use direct rendering
1839 av_picture_copy(&pict, (AVPicture *)src_frame,
1840 src_frame->format, vp->width, vp->height);
1842 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1843 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1844 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1845 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1846 if (!is->img_convert_ctx) {
1847 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1850 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1851 0, vp->height, pict.data, pict.linesize);
1853 /* workaround SDL PITCH_WORKAROUND */
1854 duplicate_right_border_pixels(vp->bmp);
1855 /* update the bitmap content */
1856 SDL_UnlockYUVOverlay(vp->bmp);
1859 vp->duration = duration;
1861 vp->serial = serial;
1863 /* now we can update the picture count */
1864 frame_queue_push(&is->pictq);
1869 static int get_video_frame(VideoState *is, AVFrame *frame)
1873 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1879 if (frame->pts != AV_NOPTS_VALUE)
1880 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1882 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1884 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1885 if (frame->pts != AV_NOPTS_VALUE) {
1886 double diff = dpts - get_master_clock(is);
1887 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1888 diff - is->frame_last_filter_delay < 0 &&
1889 is->viddec.pkt_serial == is->vidclk.serial &&
1890 is->videoq.nb_packets) {
1891 is->frame_drops_early++;
1892 av_frame_unref(frame);
1903 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1904 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1907 int nb_filters = graph->nb_filters;
1908 AVFilterInOut *outputs = NULL, *inputs = NULL;
1911 outputs = avfilter_inout_alloc();
1912 inputs = avfilter_inout_alloc();
1913 if (!outputs || !inputs) {
1914 ret = AVERROR(ENOMEM);
1918 outputs->name = av_strdup("in");
1919 outputs->filter_ctx = source_ctx;
1920 outputs->pad_idx = 0;
1921 outputs->next = NULL;
1923 inputs->name = av_strdup("out");
1924 inputs->filter_ctx = sink_ctx;
1925 inputs->pad_idx = 0;
1926 inputs->next = NULL;
1928 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1931 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1935 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1936 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1937 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1939 ret = avfilter_graph_config(graph, NULL);
1941 avfilter_inout_free(&outputs);
1942 avfilter_inout_free(&inputs);
1946 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1948 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1949 char sws_flags_str[128];
1950 char buffersrc_args[256];
1952 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1953 AVCodecContext *codec = is->video_st->codec;
1954 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1956 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1957 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1958 graph->scale_sws_opts = av_strdup(sws_flags_str);
1960 snprintf(buffersrc_args, sizeof(buffersrc_args),
1961 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1962 frame->width, frame->height, frame->format,
1963 is->video_st->time_base.num, is->video_st->time_base.den,
1964 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1965 if (fr.num && fr.den)
1966 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1968 if ((ret = avfilter_graph_create_filter(&filt_src,
1969 avfilter_get_by_name("buffer"),
1970 "ffplay_buffer", buffersrc_args, NULL,
1974 ret = avfilter_graph_create_filter(&filt_out,
1975 avfilter_get_by_name("buffersink"),
1976 "ffplay_buffersink", NULL, NULL, graph);
1980 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1983 last_filter = filt_out;
1985 /* Note: this macro adds a filter before the lastly added filter, so the
1986 * processing order of the filters is in reverse */
1987 #define INSERT_FILT(name, arg) do { \
1988 AVFilterContext *filt_ctx; \
1990 ret = avfilter_graph_create_filter(&filt_ctx, \
1991 avfilter_get_by_name(name), \
1992 "ffplay_" name, arg, NULL, graph); \
1996 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
2000 last_filter = filt_ctx; \
2003 /* SDL YUV code is not handling odd width/height for some driver
2004 * combinations, therefore we crop the picture to an even width/height. */
2005 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
2008 AVDictionaryEntry *rotate_tag = av_dict_get(is->video_st->metadata, "rotate", NULL, 0);
2009 if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
2010 if (!strcmp(rotate_tag->value, "90")) {
2011 INSERT_FILT("transpose", "clock");
2012 } else if (!strcmp(rotate_tag->value, "180")) {
2013 INSERT_FILT("hflip", NULL);
2014 INSERT_FILT("vflip", NULL);
2015 } else if (!strcmp(rotate_tag->value, "270")) {
2016 INSERT_FILT("transpose", "cclock");
2018 char rotate_buf[64];
2019 snprintf(rotate_buf, sizeof(rotate_buf), "%s*PI/180", rotate_tag->value);
2020 INSERT_FILT("rotate", rotate_buf);
2025 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
2028 is->in_video_filter = filt_src;
2029 is->out_video_filter = filt_out;
2035 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
2037 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2038 int sample_rates[2] = { 0, -1 };
2039 int64_t channel_layouts[2] = { 0, -1 };
2040 int channels[2] = { 0, -1 };
2041 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2042 char aresample_swr_opts[512] = "";
2043 AVDictionaryEntry *e = NULL;
2044 char asrc_args[256];
2047 avfilter_graph_free(&is->agraph);
2048 if (!(is->agraph = avfilter_graph_alloc()))
2049 return AVERROR(ENOMEM);
2051 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2052 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2053 if (strlen(aresample_swr_opts))
2054 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2055 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2057 ret = snprintf(asrc_args, sizeof(asrc_args),
2058 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2059 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2060 is->audio_filter_src.channels,
2061 1, is->audio_filter_src.freq);
2062 if (is->audio_filter_src.channel_layout)
2063 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2064 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2066 ret = avfilter_graph_create_filter(&filt_asrc,
2067 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2068 asrc_args, NULL, is->agraph);
2073 ret = avfilter_graph_create_filter(&filt_asink,
2074 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2075 NULL, NULL, is->agraph);
2079 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2081 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2084 if (force_output_format) {
2085 channel_layouts[0] = is->audio_tgt.channel_layout;
2086 channels [0] = is->audio_tgt.channels;
2087 sample_rates [0] = is->audio_tgt.freq;
2088 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2090 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2092 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2094 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2099 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2102 is->in_audio_filter = filt_asrc;
2103 is->out_audio_filter = filt_asink;
2107 avfilter_graph_free(&is->agraph);
2110 #endif /* CONFIG_AVFILTER */
2112 static int audio_thread(void *arg)
2114 VideoState *is = arg;
2115 AVFrame *frame = av_frame_alloc();
2118 int last_serial = -1;
2119 int64_t dec_channel_layout;
2127 return AVERROR(ENOMEM);
2130 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2134 tb = (AVRational){1, frame->sample_rate};
2137 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2140 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2141 frame->format, av_frame_get_channels(frame)) ||
2142 is->audio_filter_src.channel_layout != dec_channel_layout ||
2143 is->audio_filter_src.freq != frame->sample_rate ||
2144 is->auddec.pkt_serial != last_serial;
2147 char buf1[1024], buf2[1024];
2148 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2149 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2150 av_log(NULL, AV_LOG_DEBUG,
2151 "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",
2152 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2153 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2155 is->audio_filter_src.fmt = frame->format;
2156 is->audio_filter_src.channels = av_frame_get_channels(frame);
2157 is->audio_filter_src.channel_layout = dec_channel_layout;
2158 is->audio_filter_src.freq = frame->sample_rate;
2159 last_serial = is->auddec.pkt_serial;
2161 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2165 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2168 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2169 tb = is->out_audio_filter->inputs[0]->time_base;
2171 if (!(af = frame_queue_peek_writable(&is->sampq)))
2174 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2175 af->pos = av_frame_get_pkt_pos(frame);
2176 af->serial = is->auddec.pkt_serial;
2177 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2179 av_frame_move_ref(af->frame, frame);
2180 frame_queue_push(&is->sampq);
2183 if (is->audioq.serial != is->auddec.pkt_serial)
2186 if (ret == AVERROR_EOF)
2187 is->auddec.finished = is->auddec.pkt_serial;
2190 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2193 avfilter_graph_free(&is->agraph);
2195 av_frame_free(&frame);
2199 static int video_thread(void *arg)
2201 VideoState *is = arg;
2202 AVFrame *frame = av_frame_alloc();
2206 AVRational tb = is->video_st->time_base;
2207 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2210 AVFilterGraph *graph = avfilter_graph_alloc();
2211 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2214 enum AVPixelFormat last_format = -2;
2215 int last_serial = -1;
2216 int last_vfilter_idx = 0;
2220 ret = get_video_frame(is, frame);
2227 if ( last_w != frame->width
2228 || last_h != frame->height
2229 || last_format != frame->format
2230 || last_serial != is->viddec.pkt_serial
2231 || last_vfilter_idx != is->vfilter_idx) {
2232 av_log(NULL, AV_LOG_DEBUG,
2233 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2235 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2236 frame->width, frame->height,
2237 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2238 avfilter_graph_free(&graph);
2239 graph = avfilter_graph_alloc();
2240 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2242 event.type = FF_QUIT_EVENT;
2243 event.user.data1 = is;
2244 SDL_PushEvent(&event);
2247 filt_in = is->in_video_filter;
2248 filt_out = is->out_video_filter;
2249 last_w = frame->width;
2250 last_h = frame->height;
2251 last_format = frame->format;
2252 last_serial = is->viddec.pkt_serial;
2253 last_vfilter_idx = is->vfilter_idx;
2254 frame_rate = filt_out->inputs[0]->frame_rate;
2257 ret = av_buffersrc_add_frame(filt_in, frame);
2262 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2264 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2266 if (ret == AVERROR_EOF)
2267 is->viddec.finished = is->viddec.pkt_serial;
2272 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2273 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2274 is->frame_last_filter_delay = 0;
2275 tb = filt_out->inputs[0]->time_base;
2277 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2278 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2279 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2280 av_frame_unref(frame);
2290 avfilter_graph_free(&graph);
2292 av_frame_free(&frame);
2296 static int subtitle_thread(void *arg)
2298 VideoState *is = arg;
2303 int r, g, b, y, u, v, a;
2306 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2309 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2314 if (got_subtitle && sp->sub.format == 0) {
2315 if (sp->sub.pts != AV_NOPTS_VALUE)
2316 pts = sp->sub.pts / (double)AV_TIME_BASE;
2318 sp->serial = is->subdec.pkt_serial;
2320 for (i = 0; i < sp->sub.num_rects; i++)
2322 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2324 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2325 y = RGB_TO_Y_CCIR(r, g, b);
2326 u = RGB_TO_U_CCIR(r, g, b, 0);
2327 v = RGB_TO_V_CCIR(r, g, b, 0);
2328 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2332 /* now we can update the picture count */
2333 frame_queue_push(&is->subpq);
2334 } else if (got_subtitle) {
2335 avsubtitle_free(&sp->sub);
2341 /* copy samples for viewing in editor window */
2342 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2346 size = samples_size / sizeof(short);
2348 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2351 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2353 is->sample_array_index += len;
2354 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2355 is->sample_array_index = 0;
2360 /* return the wanted number of samples to get better sync if sync_type is video
2361 * or external master clock */
2362 static int synchronize_audio(VideoState *is, int nb_samples)
2364 int wanted_nb_samples = nb_samples;
2366 /* if not master, then we try to remove or add samples to correct the clock */
2367 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2368 double diff, avg_diff;
2369 int min_nb_samples, max_nb_samples;
2371 diff = get_clock(&is->audclk) - get_master_clock(is);
2373 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2374 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2375 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2376 /* not enough measures to have a correct estimate */
2377 is->audio_diff_avg_count++;
2379 /* estimate the A-V difference */
2380 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2382 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2383 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2384 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2385 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2386 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2388 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2389 diff, avg_diff, wanted_nb_samples - nb_samples,
2390 is->audio_clock, is->audio_diff_threshold);
2393 /* too big difference : may be initial PTS errors, so
2395 is->audio_diff_avg_count = 0;
2396 is->audio_diff_cum = 0;
2400 return wanted_nb_samples;
2404 * Decode one audio frame and return its uncompressed size.
2406 * The processed audio frame is decoded, converted if required, and
2407 * stored in is->audio_buf, with size in bytes given by the return
2410 static int audio_decode_frame(VideoState *is)
2412 int data_size, resampled_data_size;
2413 int64_t dec_channel_layout;
2414 av_unused double audio_clock0;
2415 int wanted_nb_samples;
2422 if (!(af = frame_queue_peek_readable(&is->sampq)))
2424 frame_queue_next(&is->sampq);
2425 } while (af->serial != is->audioq.serial);
2427 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2428 af->frame->nb_samples,
2429 af->frame->format, 1);
2431 dec_channel_layout =
2432 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2433 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2434 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2436 if (af->frame->format != is->audio_src.fmt ||
2437 dec_channel_layout != is->audio_src.channel_layout ||
2438 af->frame->sample_rate != is->audio_src.freq ||
2439 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2440 swr_free(&is->swr_ctx);
2441 is->swr_ctx = swr_alloc_set_opts(NULL,
2442 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2443 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2445 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2446 av_log(NULL, AV_LOG_ERROR,
2447 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2448 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2449 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2450 swr_free(&is->swr_ctx);
2453 is->audio_src.channel_layout = dec_channel_layout;
2454 is->audio_src.channels = av_frame_get_channels(af->frame);
2455 is->audio_src.freq = af->frame->sample_rate;
2456 is->audio_src.fmt = af->frame->format;
2460 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2461 uint8_t **out = &is->audio_buf1;
2462 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2463 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2466 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2469 if (wanted_nb_samples != af->frame->nb_samples) {
2470 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2471 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2472 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2476 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2477 if (!is->audio_buf1)
2478 return AVERROR(ENOMEM);
2479 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2481 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2484 if (len2 == out_count) {
2485 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2486 if (swr_init(is->swr_ctx) < 0)
2487 swr_free(&is->swr_ctx);
2489 is->audio_buf = is->audio_buf1;
2490 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2492 is->audio_buf = af->frame->data[0];
2493 resampled_data_size = data_size;
2496 audio_clock0 = is->audio_clock;
2497 /* update the audio clock with the pts */
2498 if (!isnan(af->pts))
2499 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2501 is->audio_clock = NAN;
2502 is->audio_clock_serial = af->serial;
2505 static double last_clock;
2506 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2507 is->audio_clock - last_clock,
2508 is->audio_clock, audio_clock0);
2509 last_clock = is->audio_clock;
2512 return resampled_data_size;
2515 /* prepare a new audio buffer */
2516 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2518 VideoState *is = opaque;
2519 int audio_size, len1;
2521 audio_callback_time = av_gettime_relative();
2524 if (is->audio_buf_index >= is->audio_buf_size) {
2525 audio_size = audio_decode_frame(is);
2526 if (audio_size < 0) {
2527 /* if error, just output silence */
2528 is->audio_buf = is->silence_buf;
2529 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2531 if (is->show_mode != SHOW_MODE_VIDEO)
2532 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2533 is->audio_buf_size = audio_size;
2535 is->audio_buf_index = 0;
2537 len1 = is->audio_buf_size - is->audio_buf_index;
2540 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2543 is->audio_buf_index += len1;
2545 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2546 /* Let's assume the audio driver that is used by SDL has two periods. */
2547 if (!isnan(is->audio_clock)) {
2548 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);
2549 sync_clock_to_slave(&is->extclk, &is->audclk);
2553 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2555 SDL_AudioSpec wanted_spec, spec;
2557 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2558 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2559 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2561 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2563 wanted_nb_channels = atoi(env);
2564 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2566 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2567 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2568 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2570 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2571 wanted_spec.channels = wanted_nb_channels;
2572 wanted_spec.freq = wanted_sample_rate;
2573 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2574 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2577 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2578 next_sample_rate_idx--;
2579 wanted_spec.format = AUDIO_S16SYS;
2580 wanted_spec.silence = 0;
2581 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2582 wanted_spec.callback = sdl_audio_callback;
2583 wanted_spec.userdata = opaque;
2584 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2585 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2586 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2587 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2588 if (!wanted_spec.channels) {
2589 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2590 wanted_spec.channels = wanted_nb_channels;
2591 if (!wanted_spec.freq) {
2592 av_log(NULL, AV_LOG_ERROR,
2593 "No more combinations to try, audio open failed\n");
2597 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2599 if (spec.format != AUDIO_S16SYS) {
2600 av_log(NULL, AV_LOG_ERROR,
2601 "SDL advised audio format %d is not supported!\n", spec.format);
2604 if (spec.channels != wanted_spec.channels) {
2605 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2606 if (!wanted_channel_layout) {
2607 av_log(NULL, AV_LOG_ERROR,
2608 "SDL advised channel count %d is not supported!\n", spec.channels);
2613 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2614 audio_hw_params->freq = spec.freq;
2615 audio_hw_params->channel_layout = wanted_channel_layout;
2616 audio_hw_params->channels = spec.channels;
2617 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2618 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);
2619 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2620 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2626 /* open a given stream. Return 0 if OK */
2627 static int stream_component_open(VideoState *is, int stream_index)
2629 AVFormatContext *ic = is->ic;
2630 AVCodecContext *avctx;
2632 const char *forced_codec_name = NULL;
2634 AVDictionaryEntry *t = NULL;
2635 int sample_rate, nb_channels;
2636 int64_t channel_layout;
2638 int stream_lowres = lowres;
2640 if (stream_index < 0 || stream_index >= ic->nb_streams)
2642 avctx = ic->streams[stream_index]->codec;
2644 codec = avcodec_find_decoder(avctx->codec_id);
2646 switch(avctx->codec_type){
2647 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2648 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2649 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2651 if (forced_codec_name)
2652 codec = avcodec_find_decoder_by_name(forced_codec_name);
2654 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2655 "No codec could be found with name '%s'\n", forced_codec_name);
2656 else av_log(NULL, AV_LOG_WARNING,
2657 "No codec could be found with id %d\n", avctx->codec_id);
2661 avctx->codec_id = codec->id;
2662 if(stream_lowres > av_codec_get_max_lowres(codec)){
2663 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2664 av_codec_get_max_lowres(codec));
2665 stream_lowres = av_codec_get_max_lowres(codec);
2667 av_codec_set_lowres(avctx, stream_lowres);
2669 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2670 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2671 if(codec->capabilities & CODEC_CAP_DR1)
2672 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2674 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2675 if (!av_dict_get(opts, "threads", NULL, 0))
2676 av_dict_set(&opts, "threads", "auto", 0);
2678 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2679 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2680 av_dict_set(&opts, "refcounted_frames", "1", 0);
2681 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2684 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2685 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2686 ret = AVERROR_OPTION_NOT_FOUND;
2690 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2691 switch (avctx->codec_type) {
2692 case AVMEDIA_TYPE_AUDIO:
2697 is->audio_filter_src.freq = avctx->sample_rate;
2698 is->audio_filter_src.channels = avctx->channels;
2699 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2700 is->audio_filter_src.fmt = avctx->sample_fmt;
2701 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2703 link = is->out_audio_filter->inputs[0];
2704 sample_rate = link->sample_rate;
2705 nb_channels = link->channels;
2706 channel_layout = link->channel_layout;
2709 sample_rate = avctx->sample_rate;
2710 nb_channels = avctx->channels;
2711 channel_layout = avctx->channel_layout;
2714 /* prepare audio output */
2715 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2717 is->audio_hw_buf_size = ret;
2718 is->audio_src = is->audio_tgt;
2719 is->audio_buf_size = 0;
2720 is->audio_buf_index = 0;
2722 /* init averaging filter */
2723 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2724 is->audio_diff_avg_count = 0;
2725 /* since we do not have a precise anough audio fifo fullness,
2726 we correct audio sync only if larger than this threshold */
2727 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2729 is->audio_stream = stream_index;
2730 is->audio_st = ic->streams[stream_index];
2732 packet_queue_start(&is->audioq);
2733 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2734 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2735 is->auddec.start_pts = is->audio_st->start_time;
2736 is->auddec.start_pts_tb = is->audio_st->time_base;
2738 is->audio_tid = SDL_CreateThread(audio_thread, is);
2741 case AVMEDIA_TYPE_VIDEO:
2742 is->video_stream = stream_index;
2743 is->video_st = ic->streams[stream_index];
2745 packet_queue_start(&is->videoq);
2746 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2747 is->video_tid = SDL_CreateThread(video_thread, is);
2748 is->queue_attachments_req = 1;
2750 case AVMEDIA_TYPE_SUBTITLE:
2751 is->subtitle_stream = stream_index;
2752 is->subtitle_st = ic->streams[stream_index];
2754 packet_queue_start(&is->subtitleq);
2755 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2756 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2763 av_dict_free(&opts);
2768 static void stream_component_close(VideoState *is, int stream_index)
2770 AVFormatContext *ic = is->ic;
2771 AVCodecContext *avctx;
2773 if (stream_index < 0 || stream_index >= ic->nb_streams)
2775 avctx = ic->streams[stream_index]->codec;
2777 switch (avctx->codec_type) {
2778 case AVMEDIA_TYPE_AUDIO:
2779 packet_queue_abort(&is->audioq);
2780 frame_queue_signal(&is->sampq);
2782 SDL_WaitThread(is->audio_tid, NULL);
2784 decoder_destroy(&is->auddec);
2785 packet_queue_flush(&is->audioq);
2786 swr_free(&is->swr_ctx);
2787 av_freep(&is->audio_buf1);
2788 is->audio_buf1_size = 0;
2789 is->audio_buf = NULL;
2792 av_rdft_end(is->rdft);
2793 av_freep(&is->rdft_data);
2798 case AVMEDIA_TYPE_VIDEO:
2799 packet_queue_abort(&is->videoq);
2801 /* note: we also signal this mutex to make sure we deblock the
2802 video thread in all cases */
2803 frame_queue_signal(&is->pictq);
2805 SDL_WaitThread(is->video_tid, NULL);
2807 decoder_destroy(&is->viddec);
2808 packet_queue_flush(&is->videoq);
2810 case AVMEDIA_TYPE_SUBTITLE:
2811 packet_queue_abort(&is->subtitleq);
2813 /* note: we also signal this mutex to make sure we deblock the
2814 video thread in all cases */
2815 frame_queue_signal(&is->subpq);
2817 SDL_WaitThread(is->subtitle_tid, NULL);
2819 decoder_destroy(&is->subdec);
2820 packet_queue_flush(&is->subtitleq);
2826 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2827 avcodec_close(avctx);
2828 switch (avctx->codec_type) {
2829 case AVMEDIA_TYPE_AUDIO:
2830 is->audio_st = NULL;
2831 is->audio_stream = -1;
2833 case AVMEDIA_TYPE_VIDEO:
2834 is->video_st = NULL;
2835 is->video_stream = -1;
2837 case AVMEDIA_TYPE_SUBTITLE:
2838 is->subtitle_st = NULL;
2839 is->subtitle_stream = -1;
2846 static int decode_interrupt_cb(void *ctx)
2848 VideoState *is = ctx;
2849 return is->abort_request;
2852 static int is_realtime(AVFormatContext *s)
2854 if( !strcmp(s->iformat->name, "rtp")
2855 || !strcmp(s->iformat->name, "rtsp")
2856 || !strcmp(s->iformat->name, "sdp")
2860 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2861 || !strncmp(s->filename, "udp:", 4)
2868 /* this thread gets the stream from the disk or the network */
2869 static int read_thread(void *arg)
2871 VideoState *is = arg;
2872 AVFormatContext *ic = NULL;
2874 int st_index[AVMEDIA_TYPE_NB];
2875 AVPacket pkt1, *pkt = &pkt1;
2877 int64_t stream_start_time;
2878 int pkt_in_play_range = 0;
2879 AVDictionaryEntry *t;
2880 AVDictionary **opts;
2881 int orig_nb_streams;
2882 SDL_mutex *wait_mutex = SDL_CreateMutex();
2883 int scan_all_pmts_set = 0;
2886 memset(st_index, -1, sizeof(st_index));
2887 is->last_video_stream = is->video_stream = -1;
2888 is->last_audio_stream = is->audio_stream = -1;
2889 is->last_subtitle_stream = is->subtitle_stream = -1;
2891 ic = avformat_alloc_context();
2892 ic->interrupt_callback.callback = decode_interrupt_cb;
2893 ic->interrupt_callback.opaque = is;
2894 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2895 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2896 scan_all_pmts_set = 1;
2898 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2900 print_error(is->filename, err);
2904 if (scan_all_pmts_set)
2905 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2907 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2908 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2909 ret = AVERROR_OPTION_NOT_FOUND;
2915 ic->flags |= AVFMT_FLAG_GENPTS;
2917 av_format_inject_global_side_data(ic);
2919 opts = setup_find_stream_info_opts(ic, codec_opts);
2920 orig_nb_streams = ic->nb_streams;
2922 err = avformat_find_stream_info(ic, opts);
2924 for (i = 0; i < orig_nb_streams; i++)
2925 av_dict_free(&opts[i]);
2929 av_log(NULL, AV_LOG_WARNING,
2930 "%s: could not find codec parameters\n", is->filename);
2936 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2938 if (seek_by_bytes < 0)
2939 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2941 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2943 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2944 window_title = av_asprintf("%s - %s", t->value, input_filename);
2946 /* if seeking requested, we execute it */
2947 if (start_time != AV_NOPTS_VALUE) {
2950 timestamp = start_time;
2951 /* add the stream start time */
2952 if (ic->start_time != AV_NOPTS_VALUE)
2953 timestamp += ic->start_time;
2954 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2956 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2957 is->filename, (double)timestamp / AV_TIME_BASE);
2961 is->realtime = is_realtime(ic);
2964 av_dump_format(ic, 0, is->filename, 0);
2966 for (i = 0; i < ic->nb_streams; i++) {
2967 AVStream *st = ic->streams[i];
2968 enum AVMediaType type = st->codec->codec_type;
2969 st->discard = AVDISCARD_ALL;
2970 if (wanted_stream_spec[type] && st_index[type] == -1)
2971 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2974 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2975 if (wanted_stream_spec[i] && st_index[i] == -1) {
2976 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));
2977 st_index[i] = INT_MAX;
2982 st_index[AVMEDIA_TYPE_VIDEO] =
2983 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2984 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2986 st_index[AVMEDIA_TYPE_AUDIO] =
2987 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2988 st_index[AVMEDIA_TYPE_AUDIO],
2989 st_index[AVMEDIA_TYPE_VIDEO],
2991 if (!video_disable && !subtitle_disable)
2992 st_index[AVMEDIA_TYPE_SUBTITLE] =
2993 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2994 st_index[AVMEDIA_TYPE_SUBTITLE],
2995 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2996 st_index[AVMEDIA_TYPE_AUDIO] :
2997 st_index[AVMEDIA_TYPE_VIDEO]),
3000 is->show_mode = show_mode;
3001 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3002 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
3003 AVCodecContext *avctx = st->codec;
3004 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
3006 set_default_window_size(avctx->width, avctx->height, sar);
3009 /* open the streams */
3010 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
3011 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
3015 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3016 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
3018 if (is->show_mode == SHOW_MODE_NONE)
3019 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
3021 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
3022 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
3025 if (is->video_stream < 0 && is->audio_stream < 0) {
3026 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
3032 if (infinite_buffer < 0 && is->realtime)
3033 infinite_buffer = 1;
3036 if (is->abort_request)
3038 if (is->paused != is->last_paused) {
3039 is->last_paused = is->paused;
3041 is->read_pause_return = av_read_pause(ic);
3045 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3047 (!strcmp(ic->iformat->name, "rtsp") ||
3048 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3049 /* wait 10 ms to avoid trying to get another packet */
3056 int64_t seek_target = is->seek_pos;
3057 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3058 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3059 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3060 // of the seek_pos/seek_rel variables
3062 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3064 av_log(NULL, AV_LOG_ERROR,
3065 "%s: error while seeking\n", is->ic->filename);
3067 if (is->audio_stream >= 0) {
3068 packet_queue_flush(&is->audioq);
3069 packet_queue_put(&is->audioq, &flush_pkt);
3071 if (is->subtitle_stream >= 0) {
3072 packet_queue_flush(&is->subtitleq);
3073 packet_queue_put(&is->subtitleq, &flush_pkt);
3075 if (is->video_stream >= 0) {
3076 packet_queue_flush(&is->videoq);
3077 packet_queue_put(&is->videoq, &flush_pkt);
3079 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3080 set_clock(&is->extclk, NAN, 0);
3082 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3086 is->queue_attachments_req = 1;
3089 step_to_next_frame(is);
3091 if (is->queue_attachments_req) {
3092 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3094 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3096 packet_queue_put(&is->videoq, ©);
3097 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3099 is->queue_attachments_req = 0;
3102 /* if the queue are full, no need to read more */
3103 if (infinite_buffer<1 &&
3104 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3105 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3106 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3107 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3108 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3110 SDL_LockMutex(wait_mutex);
3111 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3112 SDL_UnlockMutex(wait_mutex);
3116 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3117 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3118 if (loop != 1 && (!loop || --loop)) {
3119 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3120 } else if (autoexit) {
3125 ret = av_read_frame(ic, pkt);
3127 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !eof) {
3128 if (is->video_stream >= 0)
3129 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3130 if (is->audio_stream >= 0)
3131 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3132 if (is->subtitle_stream >= 0)
3133 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3136 if (ic->pb && ic->pb->error)
3138 SDL_LockMutex(wait_mutex);
3139 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3140 SDL_UnlockMutex(wait_mutex);
3145 /* check if packet is in play range specified by user, then queue, otherwise discard */
3146 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3147 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3148 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3149 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3150 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3151 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3152 <= ((double)duration / 1000000);
3153 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3154 packet_queue_put(&is->audioq, pkt);
3155 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3156 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3157 packet_queue_put(&is->videoq, pkt);
3158 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3159 packet_queue_put(&is->subtitleq, pkt);
3161 av_free_packet(pkt);
3164 /* wait until the end */
3165 while (!is->abort_request) {
3171 /* close each stream */
3172 if (is->audio_stream >= 0)
3173 stream_component_close(is, is->audio_stream);
3174 if (is->video_stream >= 0)
3175 stream_component_close(is, is->video_stream);
3176 if (is->subtitle_stream >= 0)
3177 stream_component_close(is, is->subtitle_stream);
3179 avformat_close_input(&ic);
3186 event.type = FF_QUIT_EVENT;
3187 event.user.data1 = is;
3188 SDL_PushEvent(&event);
3190 SDL_DestroyMutex(wait_mutex);
3194 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3198 is = av_mallocz(sizeof(VideoState));
3201 av_strlcpy(is->filename, filename, sizeof(is->filename));
3202 is->iformat = iformat;
3206 /* start video display */
3207 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3209 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3211 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3214 packet_queue_init(&is->videoq);
3215 packet_queue_init(&is->audioq);
3216 packet_queue_init(&is->subtitleq);
3218 is->continue_read_thread = SDL_CreateCond();
3220 init_clock(&is->vidclk, &is->videoq.serial);
3221 init_clock(&is->audclk, &is->audioq.serial);
3222 init_clock(&is->extclk, &is->extclk.serial);
3223 is->audio_clock_serial = -1;
3224 is->av_sync_type = av_sync_type;
3225 is->read_tid = SDL_CreateThread(read_thread, is);
3226 if (!is->read_tid) {
3234 static void stream_cycle_channel(VideoState *is, int codec_type)
3236 AVFormatContext *ic = is->ic;
3237 int start_index, stream_index;
3240 AVProgram *p = NULL;
3241 int nb_streams = is->ic->nb_streams;
3243 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3244 start_index = is->last_video_stream;
3245 old_index = is->video_stream;
3246 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3247 start_index = is->last_audio_stream;
3248 old_index = is->audio_stream;
3250 start_index = is->last_subtitle_stream;
3251 old_index = is->subtitle_stream;
3253 stream_index = start_index;
3255 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3256 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3258 nb_streams = p->nb_stream_indexes;
3259 for (start_index = 0; start_index < nb_streams; start_index++)
3260 if (p->stream_index[start_index] == stream_index)
3262 if (start_index == nb_streams)
3264 stream_index = start_index;
3269 if (++stream_index >= nb_streams)
3271 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3274 is->last_subtitle_stream = -1;
3277 if (start_index == -1)
3281 if (stream_index == start_index)
3283 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3284 if (st->codec->codec_type == codec_type) {
3285 /* check that parameters are OK */
3286 switch (codec_type) {
3287 case AVMEDIA_TYPE_AUDIO:
3288 if (st->codec->sample_rate != 0 &&
3289 st->codec->channels != 0)
3292 case AVMEDIA_TYPE_VIDEO:
3293 case AVMEDIA_TYPE_SUBTITLE:
3301 if (p && stream_index != -1)
3302 stream_index = p->stream_index[stream_index];
3303 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3304 av_get_media_type_string(codec_type),
3308 stream_component_close(is, old_index);
3309 stream_component_open(is, stream_index);
3313 static void toggle_full_screen(VideoState *is)
3315 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3316 /* OS X needs to reallocate the SDL overlays */
3318 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3319 is->pictq.queue[i].reallocate = 1;
3321 is_full_screen = !is_full_screen;
3322 video_open(is, 1, NULL);
3325 static void toggle_audio_display(VideoState *is)
3327 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3328 int next = is->show_mode;
3330 next = (next + 1) % SHOW_MODE_NB;
3331 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3332 if (is->show_mode != next) {
3333 fill_rectangle(screen,
3334 is->xleft, is->ytop, is->width, is->height,
3336 is->force_refresh = 1;
3337 is->show_mode = next;
3341 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3342 double remaining_time = 0.0;
3344 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3345 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3349 if (remaining_time > 0.0)
3350 av_usleep((int64_t)(remaining_time * 1000000.0));
3351 remaining_time = REFRESH_RATE;
3352 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3353 video_refresh(is, &remaining_time);
3358 static void seek_chapter(VideoState *is, int incr)
3360 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3363 if (!is->ic->nb_chapters)
3366 /* find the current chapter */
3367 for (i = 0; i < is->ic->nb_chapters; i++) {
3368 AVChapter *ch = is->ic->chapters[i];
3369 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3377 if (i >= is->ic->nb_chapters)
3380 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3381 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3382 AV_TIME_BASE_Q), 0, 0);
3385 /* handle an event sent by the GUI */
3386 static void event_loop(VideoState *cur_stream)
3389 double incr, pos, frac;
3393 refresh_loop_wait_event(cur_stream, &event);
3394 switch (event.type) {
3396 if (exit_on_keydown) {
3397 do_exit(cur_stream);
3400 switch (event.key.keysym.sym) {
3403 do_exit(cur_stream);
3406 toggle_full_screen(cur_stream);
3407 cur_stream->force_refresh = 1;
3411 toggle_pause(cur_stream);
3413 case SDLK_s: // S: Step to next frame
3414 step_to_next_frame(cur_stream);
3417 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3420 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3423 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3424 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3425 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3428 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3432 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3433 if (++cur_stream->vfilter_idx >= nb_vfilters)
3434 cur_stream->vfilter_idx = 0;
3436 cur_stream->vfilter_idx = 0;
3437 toggle_audio_display(cur_stream);
3440 toggle_audio_display(cur_stream);
3444 if (cur_stream->ic->nb_chapters <= 1) {
3448 seek_chapter(cur_stream, 1);
3451 if (cur_stream->ic->nb_chapters <= 1) {
3455 seek_chapter(cur_stream, -1);
3469 if (seek_by_bytes) {
3471 if (pos < 0 && cur_stream->video_stream >= 0)
3472 pos = frame_queue_last_pos(&cur_stream->pictq);
3473 if (pos < 0 && cur_stream->audio_stream >= 0)
3474 pos = frame_queue_last_pos(&cur_stream->sampq);
3476 pos = avio_tell(cur_stream->ic->pb);
3477 if (cur_stream->ic->bit_rate)
3478 incr *= cur_stream->ic->bit_rate / 8.0;
3482 stream_seek(cur_stream, pos, incr, 1);
3484 pos = get_master_clock(cur_stream);
3486 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3488 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3489 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3490 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3497 case SDL_VIDEOEXPOSE:
3498 cur_stream->force_refresh = 1;
3500 case SDL_MOUSEBUTTONDOWN:
3501 if (exit_on_mousedown) {
3502 do_exit(cur_stream);
3505 case SDL_MOUSEMOTION:
3506 if (cursor_hidden) {
3510 cursor_last_shown = av_gettime_relative();
3511 if (event.type == SDL_MOUSEBUTTONDOWN) {
3514 if (event.motion.state != SDL_PRESSED)
3518 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3519 uint64_t size = avio_size(cur_stream->ic->pb);
3520 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3524 int tns, thh, tmm, tss;
3525 tns = cur_stream->ic->duration / 1000000LL;
3527 tmm = (tns % 3600) / 60;
3529 frac = x / cur_stream->width;
3532 mm = (ns % 3600) / 60;
3534 av_log(NULL, AV_LOG_INFO,
3535 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3536 hh, mm, ss, thh, tmm, tss);
3537 ts = frac * cur_stream->ic->duration;
3538 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3539 ts += cur_stream->ic->start_time;
3540 stream_seek(cur_stream, ts, 0, 0);
3543 case SDL_VIDEORESIZE:
3544 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3545 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3547 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3548 do_exit(cur_stream);
3550 screen_width = cur_stream->width = screen->w;
3551 screen_height = cur_stream->height = screen->h;
3552 cur_stream->force_refresh = 1;
3556 do_exit(cur_stream);
3558 case FF_ALLOC_EVENT:
3559 alloc_picture(event.user.data1);
3567 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3569 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3570 return opt_default(NULL, "video_size", arg);
3573 static int opt_width(void *optctx, const char *opt, const char *arg)
3575 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3579 static int opt_height(void *optctx, const char *opt, const char *arg)
3581 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3585 static int opt_format(void *optctx, const char *opt, const char *arg)
3587 file_iformat = av_find_input_format(arg);
3588 if (!file_iformat) {
3589 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3590 return AVERROR(EINVAL);
3595 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3597 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3598 return opt_default(NULL, "pixel_format", arg);
3601 static int opt_sync(void *optctx, const char *opt, const char *arg)
3603 if (!strcmp(arg, "audio"))
3604 av_sync_type = AV_SYNC_AUDIO_MASTER;
3605 else if (!strcmp(arg, "video"))
3606 av_sync_type = AV_SYNC_VIDEO_MASTER;
3607 else if (!strcmp(arg, "ext"))
3608 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3610 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3616 static int opt_seek(void *optctx, const char *opt, const char *arg)
3618 start_time = parse_time_or_die(opt, arg, 1);
3622 static int opt_duration(void *optctx, const char *opt, const char *arg)
3624 duration = parse_time_or_die(opt, arg, 1);
3628 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3630 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3631 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3632 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3633 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3637 static void opt_input_file(void *optctx, const char *filename)
3639 if (input_filename) {
3640 av_log(NULL, AV_LOG_FATAL,
3641 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3642 filename, input_filename);
3645 if (!strcmp(filename, "-"))
3647 input_filename = filename;
3650 static int opt_codec(void *optctx, const char *opt, const char *arg)
3652 const char *spec = strchr(opt, ':');
3654 av_log(NULL, AV_LOG_ERROR,
3655 "No media specifier was specified in '%s' in option '%s'\n",
3657 return AVERROR(EINVAL);
3661 case 'a' : audio_codec_name = arg; break;
3662 case 's' : subtitle_codec_name = arg; break;
3663 case 'v' : video_codec_name = arg; break;
3665 av_log(NULL, AV_LOG_ERROR,
3666 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3667 return AVERROR(EINVAL);
3674 static const OptionDef options[] = {
3675 #include "cmdutils_common_opts.h"
3676 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3677 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3678 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3679 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3680 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3681 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3682 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3683 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3684 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3685 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3686 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3687 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3688 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3689 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3690 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3691 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3692 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3693 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3694 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3695 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3696 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3697 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3698 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3699 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3700 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3701 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3702 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3703 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3704 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3706 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3707 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3709 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3710 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3711 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3712 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3713 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3714 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3715 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3716 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3717 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3721 static void show_usage(void)
3723 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3724 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3725 av_log(NULL, AV_LOG_INFO, "\n");
3728 void show_help_default(const char *opt, const char *arg)
3730 av_log_set_callback(log_callback_help);
3732 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3733 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3735 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3736 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3737 #if !CONFIG_AVFILTER
3738 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3740 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3742 printf("\nWhile playing:\n"
3744 "f toggle full screen\n"
3746 "a cycle audio channel in the current program\n"
3747 "v cycle video channel\n"
3748 "t cycle subtitle channel in the current program\n"
3750 "w cycle video filters or show modes\n"
3751 "s activate frame-step mode\n"
3752 "left/right seek backward/forward 10 seconds\n"
3753 "down/up seek backward/forward 1 minute\n"
3754 "page down/page up seek backward/forward 10 minutes\n"
3755 "mouse click seek to percentage in file corresponding to fraction of width\n"
3759 static int lockmgr(void **mtx, enum AVLockOp op)
3762 case AV_LOCK_CREATE:
3763 *mtx = SDL_CreateMutex();
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 if (av_lockmgr_register(lockmgr)) {
3843 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3847 av_init_packet(&flush_pkt);
3848 flush_pkt.data = (uint8_t *)&flush_pkt;
3850 is = stream_open(input_filename, file_iformat);
3852 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");