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;
194 SDL_Thread *decoder_tid;
197 typedef struct VideoState {
198 SDL_Thread *read_tid;
199 AVInputFormat *iformat;
204 int queue_attachments_req;
209 int read_pause_return;
230 int audio_clock_serial;
231 double audio_diff_cum; /* used for AV difference average computation */
232 double audio_diff_avg_coef;
233 double audio_diff_threshold;
234 int audio_diff_avg_count;
237 int audio_hw_buf_size;
238 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
241 unsigned int audio_buf_size; /* in bytes */
242 unsigned int audio_buf1_size;
243 int audio_buf_index; /* in bytes */
244 int audio_write_buf_size;
245 struct AudioParams audio_src;
247 struct AudioParams audio_filter_src;
249 struct AudioParams audio_tgt;
250 struct SwrContext *swr_ctx;
251 int frame_drops_early;
252 int frame_drops_late;
255 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
257 int16_t sample_array[SAMPLE_ARRAY_SIZE];
258 int sample_array_index;
262 FFTSample *rdft_data;
264 double last_vis_time;
267 AVStream *subtitle_st;
268 PacketQueue subtitleq;
271 double frame_last_returned_time;
272 double frame_last_filter_delay;
276 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
278 struct SwsContext *img_convert_ctx;
280 SDL_Rect last_display_rect;
284 int width, height, xleft, ytop;
289 AVFilterContext *in_video_filter; // the first filter in the video chain
290 AVFilterContext *out_video_filter; // the last filter in the video chain
291 AVFilterContext *in_audio_filter; // the first filter in the audio chain
292 AVFilterContext *out_audio_filter; // the last filter in the audio chain
293 AVFilterGraph *agraph; // audio filter graph
296 int last_video_stream, last_audio_stream, last_subtitle_stream;
298 SDL_cond *continue_read_thread;
301 /* options specified by the user */
302 static AVInputFormat *file_iformat;
303 static const char *input_filename;
304 static const char *window_title;
305 static int fs_screen_width;
306 static int fs_screen_height;
307 static int default_width = 640;
308 static int default_height = 480;
309 static int screen_width = 0;
310 static int screen_height = 0;
311 static int audio_disable;
312 static int video_disable;
313 static int subtitle_disable;
314 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
315 static int seek_by_bytes = -1;
316 static int display_disable;
317 static int show_status = 1;
318 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
319 static int64_t start_time = AV_NOPTS_VALUE;
320 static int64_t duration = AV_NOPTS_VALUE;
322 static int genpts = 0;
323 static int lowres = 0;
324 static int decoder_reorder_pts = -1;
326 static int exit_on_keydown;
327 static int exit_on_mousedown;
329 static int framedrop = -1;
330 static int infinite_buffer = -1;
331 static enum ShowMode show_mode = SHOW_MODE_NONE;
332 static const char *audio_codec_name;
333 static const char *subtitle_codec_name;
334 static const char *video_codec_name;
335 double rdftspeed = 0.02;
336 static int64_t cursor_last_shown;
337 static int cursor_hidden = 0;
339 static const char **vfilters_list = NULL;
340 static int nb_vfilters = 0;
341 static char *afilters = NULL;
343 static int autorotate = 1;
345 /* current context */
346 static int is_full_screen;
347 static int64_t audio_callback_time;
349 static AVPacket flush_pkt;
351 #define FF_ALLOC_EVENT (SDL_USEREVENT)
352 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
354 static SDL_Surface *screen;
357 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
359 GROW_ARRAY(vfilters_list, nb_vfilters);
360 vfilters_list[nb_vfilters - 1] = arg;
366 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
367 enum AVSampleFormat fmt2, int64_t channel_count2)
369 /* If channel count == 1, planar and non-planar formats are the same */
370 if (channel_count1 == 1 && channel_count2 == 1)
371 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
373 return channel_count1 != channel_count2 || fmt1 != fmt2;
377 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
379 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
380 return channel_layout;
385 static void free_picture(Frame *vp);
387 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
389 MyAVPacketList *pkt1;
391 if (q->abort_request)
394 pkt1 = av_malloc(sizeof(MyAVPacketList));
399 if (pkt == &flush_pkt)
401 pkt1->serial = q->serial;
406 q->last_pkt->next = pkt1;
409 q->size += pkt1->pkt.size + sizeof(*pkt1);
410 /* XXX: should duplicate packet data in DV case */
411 SDL_CondSignal(q->cond);
415 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
419 /* duplicate the packet */
420 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
423 SDL_LockMutex(q->mutex);
424 ret = packet_queue_put_private(q, pkt);
425 SDL_UnlockMutex(q->mutex);
427 if (pkt != &flush_pkt && ret < 0)
433 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
435 AVPacket pkt1, *pkt = &pkt1;
439 pkt->stream_index = stream_index;
440 return packet_queue_put(q, pkt);
443 /* packet queue handling */
444 static void packet_queue_init(PacketQueue *q)
446 memset(q, 0, sizeof(PacketQueue));
447 q->mutex = SDL_CreateMutex();
448 q->cond = SDL_CreateCond();
449 q->abort_request = 1;
452 static void packet_queue_flush(PacketQueue *q)
454 MyAVPacketList *pkt, *pkt1;
456 SDL_LockMutex(q->mutex);
457 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
459 av_free_packet(&pkt->pkt);
466 SDL_UnlockMutex(q->mutex);
469 static void packet_queue_destroy(PacketQueue *q)
471 packet_queue_flush(q);
472 SDL_DestroyMutex(q->mutex);
473 SDL_DestroyCond(q->cond);
476 static void packet_queue_abort(PacketQueue *q)
478 SDL_LockMutex(q->mutex);
480 q->abort_request = 1;
482 SDL_CondSignal(q->cond);
484 SDL_UnlockMutex(q->mutex);
487 static void packet_queue_start(PacketQueue *q)
489 SDL_LockMutex(q->mutex);
490 q->abort_request = 0;
491 packet_queue_put_private(q, &flush_pkt);
492 SDL_UnlockMutex(q->mutex);
495 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
496 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
498 MyAVPacketList *pkt1;
501 SDL_LockMutex(q->mutex);
504 if (q->abort_request) {
511 q->first_pkt = pkt1->next;
515 q->size -= pkt1->pkt.size + sizeof(*pkt1);
518 *serial = pkt1->serial;
526 SDL_CondWait(q->cond, q->mutex);
529 SDL_UnlockMutex(q->mutex);
533 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
534 memset(d, 0, sizeof(Decoder));
537 d->empty_queue_cond = empty_queue_cond;
538 d->start_pts = AV_NOPTS_VALUE;
541 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
547 if (d->queue->abort_request)
550 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
553 if (d->queue->nb_packets == 0)
554 SDL_CondSignal(d->empty_queue_cond);
555 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
557 if (pkt.data == flush_pkt.data) {
558 avcodec_flush_buffers(d->avctx);
560 d->next_pts = d->start_pts;
561 d->next_pts_tb = d->start_pts_tb;
563 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
564 av_free_packet(&d->pkt);
565 d->pkt_temp = d->pkt = pkt;
566 d->packet_pending = 1;
569 switch (d->avctx->codec_type) {
570 case AVMEDIA_TYPE_VIDEO:
571 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
573 if (decoder_reorder_pts == -1) {
574 frame->pts = av_frame_get_best_effort_timestamp(frame);
575 } else if (decoder_reorder_pts) {
576 frame->pts = frame->pkt_pts;
578 frame->pts = frame->pkt_dts;
582 case AVMEDIA_TYPE_AUDIO:
583 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
585 AVRational tb = (AVRational){1, frame->sample_rate};
586 if (frame->pts != AV_NOPTS_VALUE)
587 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
588 else if (frame->pkt_pts != AV_NOPTS_VALUE)
589 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
590 else if (d->next_pts != AV_NOPTS_VALUE)
591 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
592 if (frame->pts != AV_NOPTS_VALUE) {
593 d->next_pts = frame->pts + frame->nb_samples;
598 case AVMEDIA_TYPE_SUBTITLE:
599 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
604 d->packet_pending = 0;
607 d->pkt_temp.pts = AV_NOPTS_VALUE;
608 if (d->pkt_temp.data) {
609 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
610 ret = d->pkt_temp.size;
611 d->pkt_temp.data += ret;
612 d->pkt_temp.size -= ret;
613 if (d->pkt_temp.size <= 0)
614 d->packet_pending = 0;
617 d->packet_pending = 0;
618 d->finished = d->pkt_serial;
622 } while (!got_frame && !d->finished);
627 static void decoder_destroy(Decoder *d) {
628 av_free_packet(&d->pkt);
631 static void frame_queue_unref_item(Frame *vp)
633 av_frame_unref(vp->frame);
634 avsubtitle_free(&vp->sub);
637 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
640 memset(f, 0, sizeof(FrameQueue));
641 if (!(f->mutex = SDL_CreateMutex()))
642 return AVERROR(ENOMEM);
643 if (!(f->cond = SDL_CreateCond()))
644 return AVERROR(ENOMEM);
646 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
647 f->keep_last = !!keep_last;
648 for (i = 0; i < f->max_size; i++)
649 if (!(f->queue[i].frame = av_frame_alloc()))
650 return AVERROR(ENOMEM);
654 static void frame_queue_destory(FrameQueue *f)
657 for (i = 0; i < f->max_size; i++) {
658 Frame *vp = &f->queue[i];
659 frame_queue_unref_item(vp);
660 av_frame_free(&vp->frame);
663 SDL_DestroyMutex(f->mutex);
664 SDL_DestroyCond(f->cond);
667 static void frame_queue_signal(FrameQueue *f)
669 SDL_LockMutex(f->mutex);
670 SDL_CondSignal(f->cond);
671 SDL_UnlockMutex(f->mutex);
674 static Frame *frame_queue_peek(FrameQueue *f)
676 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
679 static Frame *frame_queue_peek_next(FrameQueue *f)
681 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
684 static Frame *frame_queue_peek_last(FrameQueue *f)
686 return &f->queue[f->rindex];
689 static Frame *frame_queue_peek_writable(FrameQueue *f)
691 /* wait until we have space to put a new frame */
692 SDL_LockMutex(f->mutex);
693 while (f->size >= f->max_size &&
694 !f->pktq->abort_request) {
695 SDL_CondWait(f->cond, f->mutex);
697 SDL_UnlockMutex(f->mutex);
699 if (f->pktq->abort_request)
702 return &f->queue[f->windex];
705 static Frame *frame_queue_peek_readable(FrameQueue *f)
707 /* wait until we have a readable a new frame */
708 SDL_LockMutex(f->mutex);
709 while (f->size - f->rindex_shown <= 0 &&
710 !f->pktq->abort_request) {
711 SDL_CondWait(f->cond, f->mutex);
713 SDL_UnlockMutex(f->mutex);
715 if (f->pktq->abort_request)
718 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
721 static void frame_queue_push(FrameQueue *f)
723 if (++f->windex == f->max_size)
725 SDL_LockMutex(f->mutex);
727 SDL_CondSignal(f->cond);
728 SDL_UnlockMutex(f->mutex);
731 static void frame_queue_next(FrameQueue *f)
733 if (f->keep_last && !f->rindex_shown) {
737 frame_queue_unref_item(&f->queue[f->rindex]);
738 if (++f->rindex == f->max_size)
740 SDL_LockMutex(f->mutex);
742 SDL_CondSignal(f->cond);
743 SDL_UnlockMutex(f->mutex);
746 /* jump back to the previous frame if available by resetting rindex_shown */
747 static int frame_queue_prev(FrameQueue *f)
749 int ret = f->rindex_shown;
754 /* return the number of undisplayed frames in the queue */
755 static int frame_queue_nb_remaining(FrameQueue *f)
757 return f->size - f->rindex_shown;
760 /* return last shown position */
761 static int64_t frame_queue_last_pos(FrameQueue *f)
763 Frame *fp = &f->queue[f->rindex];
764 if (f->rindex_shown && fp->serial == f->pktq->serial)
770 static void decoder_abort(Decoder *d, FrameQueue *fq)
772 packet_queue_abort(d->queue);
773 frame_queue_signal(fq);
774 SDL_WaitThread(d->decoder_tid, NULL);
775 d->decoder_tid = NULL;
776 packet_queue_flush(d->queue);
779 static inline void fill_rectangle(SDL_Surface *screen,
780 int x, int y, int w, int h, int color, int update)
787 SDL_FillRect(screen, &rect, color);
788 if (update && w > 0 && h > 0)
789 SDL_UpdateRect(screen, x, y, w, h);
792 /* draw only the border of a rectangle */
793 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
797 /* fill the background */
801 w2 = width - (x + w);
807 h2 = height - (y + h);
810 fill_rectangle(screen,
814 fill_rectangle(screen,
815 xleft + width - w2, ytop,
818 fill_rectangle(screen,
822 fill_rectangle(screen,
823 xleft + w1, ytop + height - h2,
828 #define ALPHA_BLEND(a, oldp, newp, s)\
829 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
831 #define RGBA_IN(r, g, b, a, s)\
833 unsigned int v = ((const uint32_t *)(s))[0];\
834 a = (v >> 24) & 0xff;\
835 r = (v >> 16) & 0xff;\
836 g = (v >> 8) & 0xff;\
840 #define YUVA_IN(y, u, v, a, s, pal)\
842 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
843 a = (val >> 24) & 0xff;\
844 y = (val >> 16) & 0xff;\
845 u = (val >> 8) & 0xff;\
849 #define YUVA_OUT(d, y, u, v, a)\
851 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
857 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
859 int wrap, wrap3, width2, skip2;
860 int y, u, v, a, u1, v1, a1, w, h;
861 uint8_t *lum, *cb, *cr;
864 int dstx, dsty, dstw, dsth;
866 dstw = av_clip(rect->w, 0, imgw);
867 dsth = av_clip(rect->h, 0, imgh);
868 dstx = av_clip(rect->x, 0, imgw - dstw);
869 dsty = av_clip(rect->y, 0, imgh - dsth);
870 lum = dst->data[0] + dsty * dst->linesize[0];
871 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
872 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
874 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
876 wrap = dst->linesize[0];
877 wrap3 = rect->pict.linesize[0];
878 p = rect->pict.data[0];
879 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
887 YUVA_IN(y, u, v, a, p, pal);
888 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
889 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
890 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
896 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
897 YUVA_IN(y, u, v, a, p, pal);
901 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
903 YUVA_IN(y, u, v, a, p + BPP, pal);
907 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
908 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
909 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
916 YUVA_IN(y, u, v, a, p, pal);
917 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
918 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
919 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
923 p += wrap3 - dstw * BPP;
924 lum += wrap - dstw - dstx;
925 cb += dst->linesize[1] - width2 - skip2;
926 cr += dst->linesize[2] - width2 - skip2;
928 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
934 YUVA_IN(y, u, v, a, p, pal);
938 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
941 YUVA_IN(y, u, v, a, p, pal);
945 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
946 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
947 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
953 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
954 YUVA_IN(y, u, v, a, p, pal);
958 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
960 YUVA_IN(y, u, v, a, p + BPP, pal);
964 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
968 YUVA_IN(y, u, v, a, p, pal);
972 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
974 YUVA_IN(y, u, v, a, p + BPP, pal);
978 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
980 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
981 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
985 p += -wrap3 + 2 * BPP;
989 YUVA_IN(y, u, v, a, p, pal);
993 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
996 YUVA_IN(y, u, v, a, p, pal);
1000 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1001 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
1002 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
1008 p += wrap3 + (wrap3 - dstw * BPP);
1009 lum += wrap + (wrap - dstw - dstx);
1010 cb += dst->linesize[1] - width2 - skip2;
1011 cr += dst->linesize[2] - width2 - skip2;
1013 /* handle odd height */
1020 YUVA_IN(y, u, v, a, p, pal);
1021 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1022 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1023 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1029 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
1030 YUVA_IN(y, u, v, a, p, pal);
1034 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1036 YUVA_IN(y, u, v, a, p + BPP, pal);
1040 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
1041 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
1042 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
1049 YUVA_IN(y, u, v, a, p, pal);
1050 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1051 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1052 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1057 static void free_picture(Frame *vp)
1060 SDL_FreeYUVOverlay(vp->bmp);
1065 static void calculate_display_rect(SDL_Rect *rect,
1066 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
1067 int pic_width, int pic_height, AVRational pic_sar)
1070 int width, height, x, y;
1072 if (pic_sar.num == 0)
1075 aspect_ratio = av_q2d(pic_sar);
1077 if (aspect_ratio <= 0.0)
1079 aspect_ratio *= (float)pic_width / (float)pic_height;
1081 /* XXX: we suppose the screen has a 1.0 pixel ratio */
1082 height = scr_height;
1083 width = ((int)rint(height * aspect_ratio)) & ~1;
1084 if (width > scr_width) {
1086 height = ((int)rint(width / aspect_ratio)) & ~1;
1088 x = (scr_width - width) / 2;
1089 y = (scr_height - height) / 2;
1090 rect->x = scr_xleft + x;
1091 rect->y = scr_ytop + y;
1092 rect->w = FFMAX(width, 1);
1093 rect->h = FFMAX(height, 1);
1096 static void video_image_display(VideoState *is)
1104 vp = frame_queue_peek(&is->pictq);
1106 if (is->subtitle_st) {
1107 if (frame_queue_nb_remaining(&is->subpq) > 0) {
1108 sp = frame_queue_peek(&is->subpq);
1110 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
1111 SDL_LockYUVOverlay (vp->bmp);
1113 pict.data[0] = vp->bmp->pixels[0];
1114 pict.data[1] = vp->bmp->pixels[2];
1115 pict.data[2] = vp->bmp->pixels[1];
1117 pict.linesize[0] = vp->bmp->pitches[0];
1118 pict.linesize[1] = vp->bmp->pitches[2];
1119 pict.linesize[2] = vp->bmp->pitches[1];
1121 for (i = 0; i < sp->sub.num_rects; i++)
1122 blend_subrect(&pict, sp->sub.rects[i],
1123 vp->bmp->w, vp->bmp->h);
1125 SDL_UnlockYUVOverlay (vp->bmp);
1130 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1132 SDL_DisplayYUVOverlay(vp->bmp, &rect);
1134 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) {
1135 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1136 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
1137 is->last_display_rect = rect;
1142 static inline int compute_mod(int a, int b)
1144 return a < 0 ? a%b + b : a%b;
1147 static void video_audio_display(VideoState *s)
1149 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1150 int ch, channels, h, h2, bgcolor, fgcolor;
1152 int rdft_bits, nb_freq;
1154 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1156 nb_freq = 1 << (rdft_bits - 1);
1158 /* compute display index : center on currently output samples */
1159 channels = s->audio_tgt.channels;
1160 nb_display_channels = channels;
1162 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1164 delay = s->audio_write_buf_size;
1167 /* to be more precise, we take into account the time spent since
1168 the last buffer computation */
1169 if (audio_callback_time) {
1170 time_diff = av_gettime_relative() - audio_callback_time;
1171 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1174 delay += 2 * data_used;
1175 if (delay < data_used)
1178 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1179 if (s->show_mode == SHOW_MODE_WAVES) {
1181 for (i = 0; i < 1000; i += channels) {
1182 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1183 int a = s->sample_array[idx];
1184 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1185 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1186 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1188 if (h < score && (b ^ c) < 0) {
1195 s->last_i_start = i_start;
1197 i_start = s->last_i_start;
1200 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1201 if (s->show_mode == SHOW_MODE_WAVES) {
1202 fill_rectangle(screen,
1203 s->xleft, s->ytop, s->width, s->height,
1206 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1208 /* total height for one channel */
1209 h = s->height / nb_display_channels;
1210 /* graph height / 2 */
1212 for (ch = 0; ch < nb_display_channels; ch++) {
1214 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1215 for (x = 0; x < s->width; x++) {
1216 y = (s->sample_array[i] * h2) >> 15;
1223 fill_rectangle(screen,
1224 s->xleft + x, ys, 1, y,
1227 if (i >= SAMPLE_ARRAY_SIZE)
1228 i -= SAMPLE_ARRAY_SIZE;
1232 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1234 for (ch = 1; ch < nb_display_channels; ch++) {
1235 y = s->ytop + ch * h;
1236 fill_rectangle(screen,
1237 s->xleft, y, s->width, 1,
1240 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1242 nb_display_channels= FFMIN(nb_display_channels, 2);
1243 if (rdft_bits != s->rdft_bits) {
1244 av_rdft_end(s->rdft);
1245 av_free(s->rdft_data);
1246 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1247 s->rdft_bits = rdft_bits;
1248 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1252 for (ch = 0; ch < nb_display_channels; ch++) {
1253 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1255 for (x = 0; x < 2 * nb_freq; x++) {
1256 double w = (x-nb_freq) * (1.0 / nb_freq);
1257 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1259 if (i >= SAMPLE_ARRAY_SIZE)
1260 i -= SAMPLE_ARRAY_SIZE;
1262 av_rdft_calc(s->rdft, data[ch]);
1264 /* Least efficient way to do this, we should of course
1265 * directly access it but it is more than fast enough. */
1266 for (y = 0; y < s->height; y++) {
1267 double w = 1 / sqrt(nb_freq);
1268 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]));
1269 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1270 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1273 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1275 fill_rectangle(screen,
1276 s->xpos, s->height-y, 1, 1,
1280 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1283 if (s->xpos >= s->width)
1288 static void stream_close(VideoState *is)
1290 /* XXX: use a special url_shutdown call to abort parse cleanly */
1291 is->abort_request = 1;
1292 SDL_WaitThread(is->read_tid, NULL);
1293 packet_queue_destroy(&is->videoq);
1294 packet_queue_destroy(&is->audioq);
1295 packet_queue_destroy(&is->subtitleq);
1297 /* free all pictures */
1298 frame_queue_destory(&is->pictq);
1299 frame_queue_destory(&is->sampq);
1300 frame_queue_destory(&is->subpq);
1301 SDL_DestroyCond(is->continue_read_thread);
1302 #if !CONFIG_AVFILTER
1303 sws_freeContext(is->img_convert_ctx);
1308 static void do_exit(VideoState *is)
1313 av_lockmgr_register(NULL);
1316 av_freep(&vfilters_list);
1318 avformat_network_deinit();
1322 av_log(NULL, AV_LOG_QUIET, "%s", "");
1326 static void sigterm_handler(int sig)
1331 static void set_default_window_size(int width, int height, AVRational sar)
1334 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1335 default_width = rect.w;
1336 default_height = rect.h;
1339 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1341 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1344 if (is_full_screen) flags |= SDL_FULLSCREEN;
1345 else flags |= SDL_RESIZABLE;
1347 if (vp && vp->width)
1348 set_default_window_size(vp->width, vp->height, vp->sar);
1350 if (is_full_screen && fs_screen_width) {
1351 w = fs_screen_width;
1352 h = fs_screen_height;
1353 } else if (!is_full_screen && screen_width) {
1360 w = FFMIN(16383, w);
1361 if (screen && is->width == screen->w && screen->w == w
1362 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1364 screen = SDL_SetVideoMode(w, h, 0, flags);
1366 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1370 window_title = input_filename;
1371 SDL_WM_SetCaption(window_title, window_title);
1373 is->width = screen->w;
1374 is->height = screen->h;
1379 /* display the current picture, if any */
1380 static void video_display(VideoState *is)
1383 video_open(is, 0, NULL);
1384 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1385 video_audio_display(is);
1386 else if (is->video_st)
1387 video_image_display(is);
1390 static double get_clock(Clock *c)
1392 if (*c->queue_serial != c->serial)
1397 double time = av_gettime_relative() / 1000000.0;
1398 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1402 static void set_clock_at(Clock *c, double pts, int serial, double time)
1405 c->last_updated = time;
1406 c->pts_drift = c->pts - time;
1410 static void set_clock(Clock *c, double pts, int serial)
1412 double time = av_gettime_relative() / 1000000.0;
1413 set_clock_at(c, pts, serial, time);
1416 static void set_clock_speed(Clock *c, double speed)
1418 set_clock(c, get_clock(c), c->serial);
1422 static void init_clock(Clock *c, int *queue_serial)
1426 c->queue_serial = queue_serial;
1427 set_clock(c, NAN, -1);
1430 static void sync_clock_to_slave(Clock *c, Clock *slave)
1432 double clock = get_clock(c);
1433 double slave_clock = get_clock(slave);
1434 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1435 set_clock(c, slave_clock, slave->serial);
1438 static int get_master_sync_type(VideoState *is) {
1439 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1441 return AV_SYNC_VIDEO_MASTER;
1443 return AV_SYNC_AUDIO_MASTER;
1444 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1446 return AV_SYNC_AUDIO_MASTER;
1448 return AV_SYNC_EXTERNAL_CLOCK;
1450 return AV_SYNC_EXTERNAL_CLOCK;
1454 /* get the current master clock value */
1455 static double get_master_clock(VideoState *is)
1459 switch (get_master_sync_type(is)) {
1460 case AV_SYNC_VIDEO_MASTER:
1461 val = get_clock(&is->vidclk);
1463 case AV_SYNC_AUDIO_MASTER:
1464 val = get_clock(&is->audclk);
1467 val = get_clock(&is->extclk);
1473 static void check_external_clock_speed(VideoState *is) {
1474 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1475 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1476 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1477 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1478 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1479 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1481 double speed = is->extclk.speed;
1483 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1487 /* seek in the stream */
1488 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1490 if (!is->seek_req) {
1493 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1495 is->seek_flags |= AVSEEK_FLAG_BYTE;
1497 SDL_CondSignal(is->continue_read_thread);
1501 /* pause or resume the video */
1502 static void stream_toggle_pause(VideoState *is)
1505 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1506 if (is->read_pause_return != AVERROR(ENOSYS)) {
1507 is->vidclk.paused = 0;
1509 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1511 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1512 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1515 static void toggle_pause(VideoState *is)
1517 stream_toggle_pause(is);
1521 static void step_to_next_frame(VideoState *is)
1523 /* if the stream is paused unpause it, then step */
1525 stream_toggle_pause(is);
1529 static double compute_target_delay(double delay, VideoState *is)
1531 double sync_threshold, diff;
1533 /* update delay to follow master synchronisation source */
1534 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1535 /* if video is slave, we try to correct big delays by
1536 duplicating or deleting a frame */
1537 diff = get_clock(&is->vidclk) - get_master_clock(is);
1539 /* skip or repeat frame. We take into account the
1540 delay to compute the threshold. I still don't know
1541 if it is the best guess */
1542 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1543 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1544 if (diff <= -sync_threshold)
1545 delay = FFMAX(0, delay + diff);
1546 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1547 delay = delay + diff;
1548 else if (diff >= sync_threshold)
1553 av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1559 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1560 if (vp->serial == nextvp->serial) {
1561 double duration = nextvp->pts - vp->pts;
1562 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1563 return vp->duration;
1571 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1572 /* update current video pts */
1573 set_clock(&is->vidclk, pts, serial);
1574 sync_clock_to_slave(&is->extclk, &is->vidclk);
1577 /* called to display each frame */
1578 static void video_refresh(void *opaque, double *remaining_time)
1580 VideoState *is = opaque;
1585 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1586 check_external_clock_speed(is);
1588 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1589 time = av_gettime_relative() / 1000000.0;
1590 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1592 is->last_vis_time = time;
1594 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1599 if (is->force_refresh)
1600 redisplay = frame_queue_prev(&is->pictq);
1602 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1603 // nothing to do, no picture to display in the queue
1605 double last_duration, duration, delay;
1608 /* dequeue the picture */
1609 lastvp = frame_queue_peek_last(&is->pictq);
1610 vp = frame_queue_peek(&is->pictq);
1612 if (vp->serial != is->videoq.serial) {
1613 frame_queue_next(&is->pictq);
1618 if (lastvp->serial != vp->serial && !redisplay)
1619 is->frame_timer = av_gettime_relative() / 1000000.0;
1624 /* compute nominal last_duration */
1625 last_duration = vp_duration(is, lastvp, vp);
1629 delay = compute_target_delay(last_duration, is);
1631 time= av_gettime_relative()/1000000.0;
1632 if (time < is->frame_timer + delay && !redisplay) {
1633 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1637 is->frame_timer += delay;
1638 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1639 is->frame_timer = time;
1641 SDL_LockMutex(is->pictq.mutex);
1642 if (!redisplay && !isnan(vp->pts))
1643 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1644 SDL_UnlockMutex(is->pictq.mutex);
1646 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1647 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1648 duration = vp_duration(is, vp, nextvp);
1649 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1651 is->frame_drops_late++;
1652 frame_queue_next(&is->pictq);
1658 if (is->subtitle_st) {
1659 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1660 sp = frame_queue_peek(&is->subpq);
1662 if (frame_queue_nb_remaining(&is->subpq) > 1)
1663 sp2 = frame_queue_peek_next(&is->subpq);
1667 if (sp->serial != is->subtitleq.serial
1668 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1669 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1671 frame_queue_next(&is->subpq);
1679 /* display picture */
1680 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1683 frame_queue_next(&is->pictq);
1685 if (is->step && !is->paused)
1686 stream_toggle_pause(is);
1689 is->force_refresh = 0;
1691 static int64_t last_time;
1693 int aqsize, vqsize, sqsize;
1696 cur_time = av_gettime_relative();
1697 if (!last_time || (cur_time - last_time) >= 30000) {
1702 aqsize = is->audioq.size;
1704 vqsize = is->videoq.size;
1705 if (is->subtitle_st)
1706 sqsize = is->subtitleq.size;
1708 if (is->audio_st && is->video_st)
1709 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1710 else if (is->video_st)
1711 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1712 else if (is->audio_st)
1713 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1714 av_log(NULL, AV_LOG_INFO,
1715 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1716 get_master_clock(is),
1717 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1719 is->frame_drops_early + is->frame_drops_late,
1723 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1724 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1726 last_time = cur_time;
1731 /* allocate a picture (needs to do that in main thread to avoid
1732 potential locking problems */
1733 static void alloc_picture(VideoState *is)
1738 vp = &is->pictq.queue[is->pictq.windex];
1742 video_open(is, 0, vp);
1744 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1747 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1748 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1749 /* SDL allocates a buffer smaller than requested if the video
1750 * overlay hardware is unable to support the requested size. */
1751 av_log(NULL, AV_LOG_FATAL,
1752 "Error: the video system does not support an image\n"
1753 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1754 "to reduce the image size.\n", vp->width, vp->height );
1758 SDL_LockMutex(is->pictq.mutex);
1760 SDL_CondSignal(is->pictq.cond);
1761 SDL_UnlockMutex(is->pictq.mutex);
1764 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1765 int i, width, height;
1767 for (i = 0; i < 3; i++) {
1774 if (bmp->pitches[i] > width) {
1775 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1776 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1782 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1786 #if defined(DEBUG_SYNC) && 0
1787 printf("frame_type=%c pts=%0.3f\n",
1788 av_get_picture_type_char(src_frame->pict_type), pts);
1791 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1794 vp->sar = src_frame->sample_aspect_ratio;
1796 /* alloc or resize hardware picture buffer */
1797 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1798 vp->width != src_frame->width ||
1799 vp->height != src_frame->height) {
1804 vp->width = src_frame->width;
1805 vp->height = src_frame->height;
1807 /* the allocation must be done in the main thread to avoid
1808 locking problems. */
1809 event.type = FF_ALLOC_EVENT;
1810 event.user.data1 = is;
1811 SDL_PushEvent(&event);
1813 /* wait until the picture is allocated */
1814 SDL_LockMutex(is->pictq.mutex);
1815 while (!vp->allocated && !is->videoq.abort_request) {
1816 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1818 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1819 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1820 while (!vp->allocated && !is->abort_request) {
1821 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1824 SDL_UnlockMutex(is->pictq.mutex);
1826 if (is->videoq.abort_request)
1830 /* if the frame is not skipped, then display it */
1832 AVPicture pict = { { 0 } };
1834 /* get a pointer on the bitmap */
1835 SDL_LockYUVOverlay (vp->bmp);
1837 pict.data[0] = vp->bmp->pixels[0];
1838 pict.data[1] = vp->bmp->pixels[2];
1839 pict.data[2] = vp->bmp->pixels[1];
1841 pict.linesize[0] = vp->bmp->pitches[0];
1842 pict.linesize[1] = vp->bmp->pitches[2];
1843 pict.linesize[2] = vp->bmp->pitches[1];
1846 // FIXME use direct rendering
1847 av_picture_copy(&pict, (AVPicture *)src_frame,
1848 src_frame->format, vp->width, vp->height);
1850 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1851 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1852 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1853 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1854 if (!is->img_convert_ctx) {
1855 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1858 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1859 0, vp->height, pict.data, pict.linesize);
1861 /* workaround SDL PITCH_WORKAROUND */
1862 duplicate_right_border_pixels(vp->bmp);
1863 /* update the bitmap content */
1864 SDL_UnlockYUVOverlay(vp->bmp);
1867 vp->duration = duration;
1869 vp->serial = serial;
1871 /* now we can update the picture count */
1872 frame_queue_push(&is->pictq);
1877 static int get_video_frame(VideoState *is, AVFrame *frame)
1881 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1887 if (frame->pts != AV_NOPTS_VALUE)
1888 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1890 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1892 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1893 if (frame->pts != AV_NOPTS_VALUE) {
1894 double diff = dpts - get_master_clock(is);
1895 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1896 diff - is->frame_last_filter_delay < 0 &&
1897 is->viddec.pkt_serial == is->vidclk.serial &&
1898 is->videoq.nb_packets) {
1899 is->frame_drops_early++;
1900 av_frame_unref(frame);
1911 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1912 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1915 int nb_filters = graph->nb_filters;
1916 AVFilterInOut *outputs = NULL, *inputs = NULL;
1919 outputs = avfilter_inout_alloc();
1920 inputs = avfilter_inout_alloc();
1921 if (!outputs || !inputs) {
1922 ret = AVERROR(ENOMEM);
1926 outputs->name = av_strdup("in");
1927 outputs->filter_ctx = source_ctx;
1928 outputs->pad_idx = 0;
1929 outputs->next = NULL;
1931 inputs->name = av_strdup("out");
1932 inputs->filter_ctx = sink_ctx;
1933 inputs->pad_idx = 0;
1934 inputs->next = NULL;
1936 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1939 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1943 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1944 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1945 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1947 ret = avfilter_graph_config(graph, NULL);
1949 avfilter_inout_free(&outputs);
1950 avfilter_inout_free(&inputs);
1954 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1956 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1957 char sws_flags_str[128];
1958 char buffersrc_args[256];
1960 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1961 AVCodecContext *codec = is->video_st->codec;
1962 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1964 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1965 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1966 graph->scale_sws_opts = av_strdup(sws_flags_str);
1968 snprintf(buffersrc_args, sizeof(buffersrc_args),
1969 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1970 frame->width, frame->height, frame->format,
1971 is->video_st->time_base.num, is->video_st->time_base.den,
1972 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1973 if (fr.num && fr.den)
1974 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1976 if ((ret = avfilter_graph_create_filter(&filt_src,
1977 avfilter_get_by_name("buffer"),
1978 "ffplay_buffer", buffersrc_args, NULL,
1982 ret = avfilter_graph_create_filter(&filt_out,
1983 avfilter_get_by_name("buffersink"),
1984 "ffplay_buffersink", NULL, NULL, graph);
1988 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1991 last_filter = filt_out;
1993 /* Note: this macro adds a filter before the lastly added filter, so the
1994 * processing order of the filters is in reverse */
1995 #define INSERT_FILT(name, arg) do { \
1996 AVFilterContext *filt_ctx; \
1998 ret = avfilter_graph_create_filter(&filt_ctx, \
1999 avfilter_get_by_name(name), \
2000 "ffplay_" name, arg, NULL, graph); \
2004 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
2008 last_filter = filt_ctx; \
2011 /* SDL YUV code is not handling odd width/height for some driver
2012 * combinations, therefore we crop the picture to an even width/height. */
2013 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
2016 AVDictionaryEntry *rotate_tag = av_dict_get(is->video_st->metadata, "rotate", NULL, 0);
2017 if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
2018 if (!strcmp(rotate_tag->value, "90")) {
2019 INSERT_FILT("transpose", "clock");
2020 } else if (!strcmp(rotate_tag->value, "180")) {
2021 INSERT_FILT("hflip", NULL);
2022 INSERT_FILT("vflip", NULL);
2023 } else if (!strcmp(rotate_tag->value, "270")) {
2024 INSERT_FILT("transpose", "cclock");
2026 char rotate_buf[64];
2027 snprintf(rotate_buf, sizeof(rotate_buf), "%s*PI/180", rotate_tag->value);
2028 INSERT_FILT("rotate", rotate_buf);
2033 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
2036 is->in_video_filter = filt_src;
2037 is->out_video_filter = filt_out;
2043 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
2045 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2046 int sample_rates[2] = { 0, -1 };
2047 int64_t channel_layouts[2] = { 0, -1 };
2048 int channels[2] = { 0, -1 };
2049 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2050 char aresample_swr_opts[512] = "";
2051 AVDictionaryEntry *e = NULL;
2052 char asrc_args[256];
2055 avfilter_graph_free(&is->agraph);
2056 if (!(is->agraph = avfilter_graph_alloc()))
2057 return AVERROR(ENOMEM);
2059 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2060 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2061 if (strlen(aresample_swr_opts))
2062 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2063 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2065 ret = snprintf(asrc_args, sizeof(asrc_args),
2066 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2067 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2068 is->audio_filter_src.channels,
2069 1, is->audio_filter_src.freq);
2070 if (is->audio_filter_src.channel_layout)
2071 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2072 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2074 ret = avfilter_graph_create_filter(&filt_asrc,
2075 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2076 asrc_args, NULL, is->agraph);
2081 ret = avfilter_graph_create_filter(&filt_asink,
2082 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2083 NULL, NULL, is->agraph);
2087 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2089 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2092 if (force_output_format) {
2093 channel_layouts[0] = is->audio_tgt.channel_layout;
2094 channels [0] = is->audio_tgt.channels;
2095 sample_rates [0] = is->audio_tgt.freq;
2096 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2098 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2100 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2102 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2107 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2110 is->in_audio_filter = filt_asrc;
2111 is->out_audio_filter = filt_asink;
2115 avfilter_graph_free(&is->agraph);
2118 #endif /* CONFIG_AVFILTER */
2120 static int audio_thread(void *arg)
2122 VideoState *is = arg;
2123 AVFrame *frame = av_frame_alloc();
2126 int last_serial = -1;
2127 int64_t dec_channel_layout;
2135 return AVERROR(ENOMEM);
2138 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2142 tb = (AVRational){1, frame->sample_rate};
2145 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2148 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2149 frame->format, av_frame_get_channels(frame)) ||
2150 is->audio_filter_src.channel_layout != dec_channel_layout ||
2151 is->audio_filter_src.freq != frame->sample_rate ||
2152 is->auddec.pkt_serial != last_serial;
2155 char buf1[1024], buf2[1024];
2156 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2157 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2158 av_log(NULL, AV_LOG_DEBUG,
2159 "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",
2160 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2161 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2163 is->audio_filter_src.fmt = frame->format;
2164 is->audio_filter_src.channels = av_frame_get_channels(frame);
2165 is->audio_filter_src.channel_layout = dec_channel_layout;
2166 is->audio_filter_src.freq = frame->sample_rate;
2167 last_serial = is->auddec.pkt_serial;
2169 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2173 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2176 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2177 tb = is->out_audio_filter->inputs[0]->time_base;
2179 if (!(af = frame_queue_peek_writable(&is->sampq)))
2182 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2183 af->pos = av_frame_get_pkt_pos(frame);
2184 af->serial = is->auddec.pkt_serial;
2185 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2187 av_frame_move_ref(af->frame, frame);
2188 frame_queue_push(&is->sampq);
2191 if (is->audioq.serial != is->auddec.pkt_serial)
2194 if (ret == AVERROR_EOF)
2195 is->auddec.finished = is->auddec.pkt_serial;
2198 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2201 avfilter_graph_free(&is->agraph);
2203 av_frame_free(&frame);
2207 static void decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2209 packet_queue_start(d->queue);
2210 d->decoder_tid = SDL_CreateThread(fn, arg);
2213 static int video_thread(void *arg)
2215 VideoState *is = arg;
2216 AVFrame *frame = av_frame_alloc();
2220 AVRational tb = is->video_st->time_base;
2221 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2224 AVFilterGraph *graph = avfilter_graph_alloc();
2225 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2228 enum AVPixelFormat last_format = -2;
2229 int last_serial = -1;
2230 int last_vfilter_idx = 0;
2234 ret = get_video_frame(is, frame);
2241 if ( last_w != frame->width
2242 || last_h != frame->height
2243 || last_format != frame->format
2244 || last_serial != is->viddec.pkt_serial
2245 || last_vfilter_idx != is->vfilter_idx) {
2246 av_log(NULL, AV_LOG_DEBUG,
2247 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2249 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2250 frame->width, frame->height,
2251 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2252 avfilter_graph_free(&graph);
2253 graph = avfilter_graph_alloc();
2254 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2256 event.type = FF_QUIT_EVENT;
2257 event.user.data1 = is;
2258 SDL_PushEvent(&event);
2261 filt_in = is->in_video_filter;
2262 filt_out = is->out_video_filter;
2263 last_w = frame->width;
2264 last_h = frame->height;
2265 last_format = frame->format;
2266 last_serial = is->viddec.pkt_serial;
2267 last_vfilter_idx = is->vfilter_idx;
2268 frame_rate = filt_out->inputs[0]->frame_rate;
2271 ret = av_buffersrc_add_frame(filt_in, frame);
2276 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2278 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2280 if (ret == AVERROR_EOF)
2281 is->viddec.finished = is->viddec.pkt_serial;
2286 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2287 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2288 is->frame_last_filter_delay = 0;
2289 tb = filt_out->inputs[0]->time_base;
2291 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2292 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2293 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2294 av_frame_unref(frame);
2304 avfilter_graph_free(&graph);
2306 av_frame_free(&frame);
2310 static int subtitle_thread(void *arg)
2312 VideoState *is = arg;
2317 int r, g, b, y, u, v, a;
2320 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2323 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2328 if (got_subtitle && sp->sub.format == 0) {
2329 if (sp->sub.pts != AV_NOPTS_VALUE)
2330 pts = sp->sub.pts / (double)AV_TIME_BASE;
2332 sp->serial = is->subdec.pkt_serial;
2334 for (i = 0; i < sp->sub.num_rects; i++)
2336 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2338 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2339 y = RGB_TO_Y_CCIR(r, g, b);
2340 u = RGB_TO_U_CCIR(r, g, b, 0);
2341 v = RGB_TO_V_CCIR(r, g, b, 0);
2342 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2346 /* now we can update the picture count */
2347 frame_queue_push(&is->subpq);
2348 } else if (got_subtitle) {
2349 avsubtitle_free(&sp->sub);
2355 /* copy samples for viewing in editor window */
2356 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2360 size = samples_size / sizeof(short);
2362 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2365 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2367 is->sample_array_index += len;
2368 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2369 is->sample_array_index = 0;
2374 /* return the wanted number of samples to get better sync if sync_type is video
2375 * or external master clock */
2376 static int synchronize_audio(VideoState *is, int nb_samples)
2378 int wanted_nb_samples = nb_samples;
2380 /* if not master, then we try to remove or add samples to correct the clock */
2381 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2382 double diff, avg_diff;
2383 int min_nb_samples, max_nb_samples;
2385 diff = get_clock(&is->audclk) - get_master_clock(is);
2387 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2388 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2389 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2390 /* not enough measures to have a correct estimate */
2391 is->audio_diff_avg_count++;
2393 /* estimate the A-V difference */
2394 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2396 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2397 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2398 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2399 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2400 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2402 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2403 diff, avg_diff, wanted_nb_samples - nb_samples,
2404 is->audio_clock, is->audio_diff_threshold);
2407 /* too big difference : may be initial PTS errors, so
2409 is->audio_diff_avg_count = 0;
2410 is->audio_diff_cum = 0;
2414 return wanted_nb_samples;
2418 * Decode one audio frame and return its uncompressed size.
2420 * The processed audio frame is decoded, converted if required, and
2421 * stored in is->audio_buf, with size in bytes given by the return
2424 static int audio_decode_frame(VideoState *is)
2426 int data_size, resampled_data_size;
2427 int64_t dec_channel_layout;
2428 av_unused double audio_clock0;
2429 int wanted_nb_samples;
2436 if (!(af = frame_queue_peek_readable(&is->sampq)))
2438 frame_queue_next(&is->sampq);
2439 } while (af->serial != is->audioq.serial);
2441 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2442 af->frame->nb_samples,
2443 af->frame->format, 1);
2445 dec_channel_layout =
2446 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2447 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2448 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2450 if (af->frame->format != is->audio_src.fmt ||
2451 dec_channel_layout != is->audio_src.channel_layout ||
2452 af->frame->sample_rate != is->audio_src.freq ||
2453 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2454 swr_free(&is->swr_ctx);
2455 is->swr_ctx = swr_alloc_set_opts(NULL,
2456 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2457 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2459 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2460 av_log(NULL, AV_LOG_ERROR,
2461 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2462 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2463 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2464 swr_free(&is->swr_ctx);
2467 is->audio_src.channel_layout = dec_channel_layout;
2468 is->audio_src.channels = av_frame_get_channels(af->frame);
2469 is->audio_src.freq = af->frame->sample_rate;
2470 is->audio_src.fmt = af->frame->format;
2474 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2475 uint8_t **out = &is->audio_buf1;
2476 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2477 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2480 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2483 if (wanted_nb_samples != af->frame->nb_samples) {
2484 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2485 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2486 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2490 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2491 if (!is->audio_buf1)
2492 return AVERROR(ENOMEM);
2493 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2495 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2498 if (len2 == out_count) {
2499 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2500 if (swr_init(is->swr_ctx) < 0)
2501 swr_free(&is->swr_ctx);
2503 is->audio_buf = is->audio_buf1;
2504 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2506 is->audio_buf = af->frame->data[0];
2507 resampled_data_size = data_size;
2510 audio_clock0 = is->audio_clock;
2511 /* update the audio clock with the pts */
2512 if (!isnan(af->pts))
2513 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2515 is->audio_clock = NAN;
2516 is->audio_clock_serial = af->serial;
2519 static double last_clock;
2520 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2521 is->audio_clock - last_clock,
2522 is->audio_clock, audio_clock0);
2523 last_clock = is->audio_clock;
2526 return resampled_data_size;
2529 /* prepare a new audio buffer */
2530 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2532 VideoState *is = opaque;
2533 int audio_size, len1;
2535 audio_callback_time = av_gettime_relative();
2538 if (is->audio_buf_index >= is->audio_buf_size) {
2539 audio_size = audio_decode_frame(is);
2540 if (audio_size < 0) {
2541 /* if error, just output silence */
2542 is->audio_buf = is->silence_buf;
2543 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2545 if (is->show_mode != SHOW_MODE_VIDEO)
2546 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2547 is->audio_buf_size = audio_size;
2549 is->audio_buf_index = 0;
2551 len1 = is->audio_buf_size - is->audio_buf_index;
2554 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2557 is->audio_buf_index += len1;
2559 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2560 /* Let's assume the audio driver that is used by SDL has two periods. */
2561 if (!isnan(is->audio_clock)) {
2562 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);
2563 sync_clock_to_slave(&is->extclk, &is->audclk);
2567 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2569 SDL_AudioSpec wanted_spec, spec;
2571 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2572 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2573 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2575 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2577 wanted_nb_channels = atoi(env);
2578 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2580 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2581 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2582 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2584 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2585 wanted_spec.channels = wanted_nb_channels;
2586 wanted_spec.freq = wanted_sample_rate;
2587 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2588 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2591 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2592 next_sample_rate_idx--;
2593 wanted_spec.format = AUDIO_S16SYS;
2594 wanted_spec.silence = 0;
2595 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2596 wanted_spec.callback = sdl_audio_callback;
2597 wanted_spec.userdata = opaque;
2598 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2599 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2600 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2601 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2602 if (!wanted_spec.channels) {
2603 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2604 wanted_spec.channels = wanted_nb_channels;
2605 if (!wanted_spec.freq) {
2606 av_log(NULL, AV_LOG_ERROR,
2607 "No more combinations to try, audio open failed\n");
2611 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2613 if (spec.format != AUDIO_S16SYS) {
2614 av_log(NULL, AV_LOG_ERROR,
2615 "SDL advised audio format %d is not supported!\n", spec.format);
2618 if (spec.channels != wanted_spec.channels) {
2619 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2620 if (!wanted_channel_layout) {
2621 av_log(NULL, AV_LOG_ERROR,
2622 "SDL advised channel count %d is not supported!\n", spec.channels);
2627 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2628 audio_hw_params->freq = spec.freq;
2629 audio_hw_params->channel_layout = wanted_channel_layout;
2630 audio_hw_params->channels = spec.channels;
2631 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2632 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);
2633 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2634 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2640 /* open a given stream. Return 0 if OK */
2641 static int stream_component_open(VideoState *is, int stream_index)
2643 AVFormatContext *ic = is->ic;
2644 AVCodecContext *avctx;
2646 const char *forced_codec_name = NULL;
2648 AVDictionaryEntry *t = NULL;
2649 int sample_rate, nb_channels;
2650 int64_t channel_layout;
2652 int stream_lowres = lowres;
2654 if (stream_index < 0 || stream_index >= ic->nb_streams)
2656 avctx = ic->streams[stream_index]->codec;
2658 codec = avcodec_find_decoder(avctx->codec_id);
2660 switch(avctx->codec_type){
2661 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2662 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2663 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2665 if (forced_codec_name)
2666 codec = avcodec_find_decoder_by_name(forced_codec_name);
2668 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2669 "No codec could be found with name '%s'\n", forced_codec_name);
2670 else av_log(NULL, AV_LOG_WARNING,
2671 "No codec could be found with id %d\n", avctx->codec_id);
2675 avctx->codec_id = codec->id;
2676 if(stream_lowres > av_codec_get_max_lowres(codec)){
2677 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2678 av_codec_get_max_lowres(codec));
2679 stream_lowres = av_codec_get_max_lowres(codec);
2681 av_codec_set_lowres(avctx, stream_lowres);
2683 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2684 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2685 if(codec->capabilities & CODEC_CAP_DR1)
2686 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2688 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2689 if (!av_dict_get(opts, "threads", NULL, 0))
2690 av_dict_set(&opts, "threads", "auto", 0);
2692 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2693 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2694 av_dict_set(&opts, "refcounted_frames", "1", 0);
2695 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2698 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2699 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2700 ret = AVERROR_OPTION_NOT_FOUND;
2705 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2706 switch (avctx->codec_type) {
2707 case AVMEDIA_TYPE_AUDIO:
2712 is->audio_filter_src.freq = avctx->sample_rate;
2713 is->audio_filter_src.channels = avctx->channels;
2714 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2715 is->audio_filter_src.fmt = avctx->sample_fmt;
2716 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2718 link = is->out_audio_filter->inputs[0];
2719 sample_rate = link->sample_rate;
2720 nb_channels = link->channels;
2721 channel_layout = link->channel_layout;
2724 sample_rate = avctx->sample_rate;
2725 nb_channels = avctx->channels;
2726 channel_layout = avctx->channel_layout;
2729 /* prepare audio output */
2730 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2732 is->audio_hw_buf_size = ret;
2733 is->audio_src = is->audio_tgt;
2734 is->audio_buf_size = 0;
2735 is->audio_buf_index = 0;
2737 /* init averaging filter */
2738 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2739 is->audio_diff_avg_count = 0;
2740 /* since we do not have a precise anough audio fifo fullness,
2741 we correct audio sync only if larger than this threshold */
2742 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2744 is->audio_stream = stream_index;
2745 is->audio_st = ic->streams[stream_index];
2747 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2748 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2749 is->auddec.start_pts = is->audio_st->start_time;
2750 is->auddec.start_pts_tb = is->audio_st->time_base;
2752 decoder_start(&is->auddec, audio_thread, is);
2755 case AVMEDIA_TYPE_VIDEO:
2756 is->video_stream = stream_index;
2757 is->video_st = ic->streams[stream_index];
2759 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2760 decoder_start(&is->viddec, video_thread, is);
2761 is->queue_attachments_req = 1;
2763 case AVMEDIA_TYPE_SUBTITLE:
2764 is->subtitle_stream = stream_index;
2765 is->subtitle_st = ic->streams[stream_index];
2767 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2768 decoder_start(&is->subdec, subtitle_thread, is);
2775 av_dict_free(&opts);
2780 static void stream_component_close(VideoState *is, int stream_index)
2782 AVFormatContext *ic = is->ic;
2783 AVCodecContext *avctx;
2785 if (stream_index < 0 || stream_index >= ic->nb_streams)
2787 avctx = ic->streams[stream_index]->codec;
2789 switch (avctx->codec_type) {
2790 case AVMEDIA_TYPE_AUDIO:
2791 decoder_abort(&is->auddec, &is->sampq);
2793 decoder_destroy(&is->auddec);
2794 swr_free(&is->swr_ctx);
2795 av_freep(&is->audio_buf1);
2796 is->audio_buf1_size = 0;
2797 is->audio_buf = NULL;
2800 av_rdft_end(is->rdft);
2801 av_freep(&is->rdft_data);
2806 case AVMEDIA_TYPE_VIDEO:
2807 decoder_abort(&is->viddec, &is->pictq);
2808 decoder_destroy(&is->viddec);
2810 case AVMEDIA_TYPE_SUBTITLE:
2811 decoder_abort(&is->subdec, &is->subpq);
2812 decoder_destroy(&is->subdec);
2818 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2819 avcodec_close(avctx);
2820 switch (avctx->codec_type) {
2821 case AVMEDIA_TYPE_AUDIO:
2822 is->audio_st = NULL;
2823 is->audio_stream = -1;
2825 case AVMEDIA_TYPE_VIDEO:
2826 is->video_st = NULL;
2827 is->video_stream = -1;
2829 case AVMEDIA_TYPE_SUBTITLE:
2830 is->subtitle_st = NULL;
2831 is->subtitle_stream = -1;
2838 static int decode_interrupt_cb(void *ctx)
2840 VideoState *is = ctx;
2841 return is->abort_request;
2844 static int is_realtime(AVFormatContext *s)
2846 if( !strcmp(s->iformat->name, "rtp")
2847 || !strcmp(s->iformat->name, "rtsp")
2848 || !strcmp(s->iformat->name, "sdp")
2852 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2853 || !strncmp(s->filename, "udp:", 4)
2860 /* this thread gets the stream from the disk or the network */
2861 static int read_thread(void *arg)
2863 VideoState *is = arg;
2864 AVFormatContext *ic = NULL;
2866 int st_index[AVMEDIA_TYPE_NB];
2867 AVPacket pkt1, *pkt = &pkt1;
2868 int64_t stream_start_time;
2869 int pkt_in_play_range = 0;
2870 AVDictionaryEntry *t;
2871 AVDictionary **opts;
2872 int orig_nb_streams;
2873 SDL_mutex *wait_mutex = SDL_CreateMutex();
2874 int scan_all_pmts_set = 0;
2877 memset(st_index, -1, sizeof(st_index));
2878 is->last_video_stream = is->video_stream = -1;
2879 is->last_audio_stream = is->audio_stream = -1;
2880 is->last_subtitle_stream = is->subtitle_stream = -1;
2883 ic = avformat_alloc_context();
2884 ic->interrupt_callback.callback = decode_interrupt_cb;
2885 ic->interrupt_callback.opaque = is;
2886 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2887 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2888 scan_all_pmts_set = 1;
2890 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2892 print_error(is->filename, err);
2896 if (scan_all_pmts_set)
2897 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2899 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2900 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2901 ret = AVERROR_OPTION_NOT_FOUND;
2907 ic->flags |= AVFMT_FLAG_GENPTS;
2909 av_format_inject_global_side_data(ic);
2911 opts = setup_find_stream_info_opts(ic, codec_opts);
2912 orig_nb_streams = ic->nb_streams;
2914 err = avformat_find_stream_info(ic, opts);
2916 for (i = 0; i < orig_nb_streams; i++)
2917 av_dict_free(&opts[i]);
2921 av_log(NULL, AV_LOG_WARNING,
2922 "%s: could not find codec parameters\n", is->filename);
2928 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2930 if (seek_by_bytes < 0)
2931 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2933 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2935 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2936 window_title = av_asprintf("%s - %s", t->value, input_filename);
2938 /* if seeking requested, we execute it */
2939 if (start_time != AV_NOPTS_VALUE) {
2942 timestamp = start_time;
2943 /* add the stream start time */
2944 if (ic->start_time != AV_NOPTS_VALUE)
2945 timestamp += ic->start_time;
2946 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2948 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2949 is->filename, (double)timestamp / AV_TIME_BASE);
2953 is->realtime = is_realtime(ic);
2956 av_dump_format(ic, 0, is->filename, 0);
2958 for (i = 0; i < ic->nb_streams; i++) {
2959 AVStream *st = ic->streams[i];
2960 enum AVMediaType type = st->codec->codec_type;
2961 st->discard = AVDISCARD_ALL;
2962 if (wanted_stream_spec[type] && st_index[type] == -1)
2963 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2966 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2967 if (wanted_stream_spec[i] && st_index[i] == -1) {
2968 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));
2969 st_index[i] = INT_MAX;
2974 st_index[AVMEDIA_TYPE_VIDEO] =
2975 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2976 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2978 st_index[AVMEDIA_TYPE_AUDIO] =
2979 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2980 st_index[AVMEDIA_TYPE_AUDIO],
2981 st_index[AVMEDIA_TYPE_VIDEO],
2983 if (!video_disable && !subtitle_disable)
2984 st_index[AVMEDIA_TYPE_SUBTITLE] =
2985 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2986 st_index[AVMEDIA_TYPE_SUBTITLE],
2987 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2988 st_index[AVMEDIA_TYPE_AUDIO] :
2989 st_index[AVMEDIA_TYPE_VIDEO]),
2992 is->show_mode = show_mode;
2993 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2994 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2995 AVCodecContext *avctx = st->codec;
2996 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2998 set_default_window_size(avctx->width, avctx->height, sar);
3001 /* open the streams */
3002 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
3003 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
3007 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3008 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
3010 if (is->show_mode == SHOW_MODE_NONE)
3011 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
3013 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
3014 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
3017 if (is->video_stream < 0 && is->audio_stream < 0) {
3018 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
3024 if (infinite_buffer < 0 && is->realtime)
3025 infinite_buffer = 1;
3028 if (is->abort_request)
3030 if (is->paused != is->last_paused) {
3031 is->last_paused = is->paused;
3033 is->read_pause_return = av_read_pause(ic);
3037 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3039 (!strcmp(ic->iformat->name, "rtsp") ||
3040 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3041 /* wait 10 ms to avoid trying to get another packet */
3048 int64_t seek_target = is->seek_pos;
3049 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3050 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3051 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3052 // of the seek_pos/seek_rel variables
3054 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3056 av_log(NULL, AV_LOG_ERROR,
3057 "%s: error while seeking\n", is->ic->filename);
3059 if (is->audio_stream >= 0) {
3060 packet_queue_flush(&is->audioq);
3061 packet_queue_put(&is->audioq, &flush_pkt);
3063 if (is->subtitle_stream >= 0) {
3064 packet_queue_flush(&is->subtitleq);
3065 packet_queue_put(&is->subtitleq, &flush_pkt);
3067 if (is->video_stream >= 0) {
3068 packet_queue_flush(&is->videoq);
3069 packet_queue_put(&is->videoq, &flush_pkt);
3071 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3072 set_clock(&is->extclk, NAN, 0);
3074 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3078 is->queue_attachments_req = 1;
3081 step_to_next_frame(is);
3083 if (is->queue_attachments_req) {
3084 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3086 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3088 packet_queue_put(&is->videoq, ©);
3089 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3091 is->queue_attachments_req = 0;
3094 /* if the queue are full, no need to read more */
3095 if (infinite_buffer<1 &&
3096 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3097 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3098 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3099 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3100 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3102 SDL_LockMutex(wait_mutex);
3103 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3104 SDL_UnlockMutex(wait_mutex);
3108 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3109 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3110 if (loop != 1 && (!loop || --loop)) {
3111 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3112 } else if (autoexit) {
3117 ret = av_read_frame(ic, pkt);
3119 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3120 if (is->video_stream >= 0)
3121 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3122 if (is->audio_stream >= 0)
3123 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3124 if (is->subtitle_stream >= 0)
3125 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3128 if (ic->pb && ic->pb->error)
3130 SDL_LockMutex(wait_mutex);
3131 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3132 SDL_UnlockMutex(wait_mutex);
3137 /* check if packet is in play range specified by user, then queue, otherwise discard */
3138 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3139 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3140 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3141 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3142 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3143 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3144 <= ((double)duration / 1000000);
3145 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3146 packet_queue_put(&is->audioq, pkt);
3147 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3148 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3149 packet_queue_put(&is->videoq, pkt);
3150 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3151 packet_queue_put(&is->subtitleq, pkt);
3153 av_free_packet(pkt);
3156 /* wait until the end */
3157 while (!is->abort_request) {
3163 /* close each stream */
3164 if (is->audio_stream >= 0)
3165 stream_component_close(is, is->audio_stream);
3166 if (is->video_stream >= 0)
3167 stream_component_close(is, is->video_stream);
3168 if (is->subtitle_stream >= 0)
3169 stream_component_close(is, is->subtitle_stream);
3171 avformat_close_input(&ic);
3178 event.type = FF_QUIT_EVENT;
3179 event.user.data1 = is;
3180 SDL_PushEvent(&event);
3182 SDL_DestroyMutex(wait_mutex);
3186 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3190 is = av_mallocz(sizeof(VideoState));
3193 av_strlcpy(is->filename, filename, sizeof(is->filename));
3194 is->iformat = iformat;
3198 /* start video display */
3199 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3201 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3203 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3206 packet_queue_init(&is->videoq);
3207 packet_queue_init(&is->audioq);
3208 packet_queue_init(&is->subtitleq);
3210 is->continue_read_thread = SDL_CreateCond();
3212 init_clock(&is->vidclk, &is->videoq.serial);
3213 init_clock(&is->audclk, &is->audioq.serial);
3214 init_clock(&is->extclk, &is->extclk.serial);
3215 is->audio_clock_serial = -1;
3216 is->av_sync_type = av_sync_type;
3217 is->read_tid = SDL_CreateThread(read_thread, is);
3218 if (!is->read_tid) {
3226 static void stream_cycle_channel(VideoState *is, int codec_type)
3228 AVFormatContext *ic = is->ic;
3229 int start_index, stream_index;
3232 AVProgram *p = NULL;
3233 int nb_streams = is->ic->nb_streams;
3235 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3236 start_index = is->last_video_stream;
3237 old_index = is->video_stream;
3238 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3239 start_index = is->last_audio_stream;
3240 old_index = is->audio_stream;
3242 start_index = is->last_subtitle_stream;
3243 old_index = is->subtitle_stream;
3245 stream_index = start_index;
3247 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3248 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3250 nb_streams = p->nb_stream_indexes;
3251 for (start_index = 0; start_index < nb_streams; start_index++)
3252 if (p->stream_index[start_index] == stream_index)
3254 if (start_index == nb_streams)
3256 stream_index = start_index;
3261 if (++stream_index >= nb_streams)
3263 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3266 is->last_subtitle_stream = -1;
3269 if (start_index == -1)
3273 if (stream_index == start_index)
3275 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3276 if (st->codec->codec_type == codec_type) {
3277 /* check that parameters are OK */
3278 switch (codec_type) {
3279 case AVMEDIA_TYPE_AUDIO:
3280 if (st->codec->sample_rate != 0 &&
3281 st->codec->channels != 0)
3284 case AVMEDIA_TYPE_VIDEO:
3285 case AVMEDIA_TYPE_SUBTITLE:
3293 if (p && stream_index != -1)
3294 stream_index = p->stream_index[stream_index];
3295 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3296 av_get_media_type_string(codec_type),
3300 stream_component_close(is, old_index);
3301 stream_component_open(is, stream_index);
3305 static void toggle_full_screen(VideoState *is)
3307 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3308 /* OS X needs to reallocate the SDL overlays */
3310 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3311 is->pictq.queue[i].reallocate = 1;
3313 is_full_screen = !is_full_screen;
3314 video_open(is, 1, NULL);
3317 static void toggle_audio_display(VideoState *is)
3319 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3320 int next = is->show_mode;
3322 next = (next + 1) % SHOW_MODE_NB;
3323 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3324 if (is->show_mode != next) {
3325 fill_rectangle(screen,
3326 is->xleft, is->ytop, is->width, is->height,
3328 is->force_refresh = 1;
3329 is->show_mode = next;
3333 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3334 double remaining_time = 0.0;
3336 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3337 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3341 if (remaining_time > 0.0)
3342 av_usleep((int64_t)(remaining_time * 1000000.0));
3343 remaining_time = REFRESH_RATE;
3344 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3345 video_refresh(is, &remaining_time);
3350 static void seek_chapter(VideoState *is, int incr)
3352 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3355 if (!is->ic->nb_chapters)
3358 /* find the current chapter */
3359 for (i = 0; i < is->ic->nb_chapters; i++) {
3360 AVChapter *ch = is->ic->chapters[i];
3361 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3369 if (i >= is->ic->nb_chapters)
3372 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3373 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3374 AV_TIME_BASE_Q), 0, 0);
3377 /* handle an event sent by the GUI */
3378 static void event_loop(VideoState *cur_stream)
3381 double incr, pos, frac;
3385 refresh_loop_wait_event(cur_stream, &event);
3386 switch (event.type) {
3388 if (exit_on_keydown) {
3389 do_exit(cur_stream);
3392 switch (event.key.keysym.sym) {
3395 do_exit(cur_stream);
3398 toggle_full_screen(cur_stream);
3399 cur_stream->force_refresh = 1;
3403 toggle_pause(cur_stream);
3405 case SDLK_s: // S: Step to next frame
3406 step_to_next_frame(cur_stream);
3409 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3412 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3415 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3416 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3417 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3420 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3424 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3425 if (++cur_stream->vfilter_idx >= nb_vfilters)
3426 cur_stream->vfilter_idx = 0;
3428 cur_stream->vfilter_idx = 0;
3429 toggle_audio_display(cur_stream);
3432 toggle_audio_display(cur_stream);
3436 if (cur_stream->ic->nb_chapters <= 1) {
3440 seek_chapter(cur_stream, 1);
3443 if (cur_stream->ic->nb_chapters <= 1) {
3447 seek_chapter(cur_stream, -1);
3461 if (seek_by_bytes) {
3463 if (pos < 0 && cur_stream->video_stream >= 0)
3464 pos = frame_queue_last_pos(&cur_stream->pictq);
3465 if (pos < 0 && cur_stream->audio_stream >= 0)
3466 pos = frame_queue_last_pos(&cur_stream->sampq);
3468 pos = avio_tell(cur_stream->ic->pb);
3469 if (cur_stream->ic->bit_rate)
3470 incr *= cur_stream->ic->bit_rate / 8.0;
3474 stream_seek(cur_stream, pos, incr, 1);
3476 pos = get_master_clock(cur_stream);
3478 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3480 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3481 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3482 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3489 case SDL_VIDEOEXPOSE:
3490 cur_stream->force_refresh = 1;
3492 case SDL_MOUSEBUTTONDOWN:
3493 if (exit_on_mousedown) {
3494 do_exit(cur_stream);
3497 case SDL_MOUSEMOTION:
3498 if (cursor_hidden) {
3502 cursor_last_shown = av_gettime_relative();
3503 if (event.type == SDL_MOUSEBUTTONDOWN) {
3506 if (event.motion.state != SDL_PRESSED)
3510 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3511 uint64_t size = avio_size(cur_stream->ic->pb);
3512 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3516 int tns, thh, tmm, tss;
3517 tns = cur_stream->ic->duration / 1000000LL;
3519 tmm = (tns % 3600) / 60;
3521 frac = x / cur_stream->width;
3524 mm = (ns % 3600) / 60;
3526 av_log(NULL, AV_LOG_INFO,
3527 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3528 hh, mm, ss, thh, tmm, tss);
3529 ts = frac * cur_stream->ic->duration;
3530 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3531 ts += cur_stream->ic->start_time;
3532 stream_seek(cur_stream, ts, 0, 0);
3535 case SDL_VIDEORESIZE:
3536 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3537 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3539 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3540 do_exit(cur_stream);
3542 screen_width = cur_stream->width = screen->w;
3543 screen_height = cur_stream->height = screen->h;
3544 cur_stream->force_refresh = 1;
3548 do_exit(cur_stream);
3550 case FF_ALLOC_EVENT:
3551 alloc_picture(event.user.data1);
3559 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3561 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3562 return opt_default(NULL, "video_size", arg);
3565 static int opt_width(void *optctx, const char *opt, const char *arg)
3567 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3571 static int opt_height(void *optctx, const char *opt, const char *arg)
3573 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3577 static int opt_format(void *optctx, const char *opt, const char *arg)
3579 file_iformat = av_find_input_format(arg);
3580 if (!file_iformat) {
3581 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3582 return AVERROR(EINVAL);
3587 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3589 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3590 return opt_default(NULL, "pixel_format", arg);
3593 static int opt_sync(void *optctx, const char *opt, const char *arg)
3595 if (!strcmp(arg, "audio"))
3596 av_sync_type = AV_SYNC_AUDIO_MASTER;
3597 else if (!strcmp(arg, "video"))
3598 av_sync_type = AV_SYNC_VIDEO_MASTER;
3599 else if (!strcmp(arg, "ext"))
3600 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3602 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3608 static int opt_seek(void *optctx, const char *opt, const char *arg)
3610 start_time = parse_time_or_die(opt, arg, 1);
3614 static int opt_duration(void *optctx, const char *opt, const char *arg)
3616 duration = parse_time_or_die(opt, arg, 1);
3620 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3622 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3623 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3624 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3625 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3629 static void opt_input_file(void *optctx, const char *filename)
3631 if (input_filename) {
3632 av_log(NULL, AV_LOG_FATAL,
3633 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3634 filename, input_filename);
3637 if (!strcmp(filename, "-"))
3639 input_filename = filename;
3642 static int opt_codec(void *optctx, const char *opt, const char *arg)
3644 const char *spec = strchr(opt, ':');
3646 av_log(NULL, AV_LOG_ERROR,
3647 "No media specifier was specified in '%s' in option '%s'\n",
3649 return AVERROR(EINVAL);
3653 case 'a' : audio_codec_name = arg; break;
3654 case 's' : subtitle_codec_name = arg; break;
3655 case 'v' : video_codec_name = arg; break;
3657 av_log(NULL, AV_LOG_ERROR,
3658 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3659 return AVERROR(EINVAL);
3666 static const OptionDef options[] = {
3667 #include "cmdutils_common_opts.h"
3668 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3669 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3670 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3671 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3672 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3673 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3674 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3675 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3676 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3677 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3678 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3679 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3680 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3681 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3682 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3683 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3684 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3685 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3686 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3687 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3688 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3689 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3690 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3691 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3692 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3693 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3694 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3695 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3696 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3698 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3699 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3701 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3702 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3703 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3704 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3705 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3706 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3707 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3708 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3709 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3713 static void show_usage(void)
3715 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3716 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3717 av_log(NULL, AV_LOG_INFO, "\n");
3720 void show_help_default(const char *opt, const char *arg)
3722 av_log_set_callback(log_callback_help);
3724 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3725 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3727 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3728 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3729 #if !CONFIG_AVFILTER
3730 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3732 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3734 printf("\nWhile playing:\n"
3736 "f toggle full screen\n"
3738 "a cycle audio channel in the current program\n"
3739 "v cycle video channel\n"
3740 "t cycle subtitle channel in the current program\n"
3742 "w cycle video filters or show modes\n"
3743 "s activate frame-step mode\n"
3744 "left/right seek backward/forward 10 seconds\n"
3745 "down/up seek backward/forward 1 minute\n"
3746 "page down/page up seek backward/forward 10 minutes\n"
3747 "mouse click seek to percentage in file corresponding to fraction of width\n"
3751 static int lockmgr(void **mtx, enum AVLockOp op)
3754 case AV_LOCK_CREATE:
3755 *mtx = SDL_CreateMutex();
3759 case AV_LOCK_OBTAIN:
3760 return !!SDL_LockMutex(*mtx);
3761 case AV_LOCK_RELEASE:
3762 return !!SDL_UnlockMutex(*mtx);
3763 case AV_LOCK_DESTROY:
3764 SDL_DestroyMutex(*mtx);
3770 /* Called from the main */
3771 int main(int argc, char **argv)
3775 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3777 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3778 parse_loglevel(argc, argv, options);
3780 /* register all codecs, demux and protocols */
3782 avdevice_register_all();
3785 avfilter_register_all();
3788 avformat_network_init();
3792 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3793 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3795 show_banner(argc, argv, options);
3797 parse_options(NULL, argc, argv, options, opt_input_file);
3799 if (!input_filename) {
3801 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3802 av_log(NULL, AV_LOG_FATAL,
3803 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3807 if (display_disable) {
3810 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3812 flags &= ~SDL_INIT_AUDIO;
3813 if (display_disable)
3814 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3815 #if !defined(_WIN32) && !defined(__APPLE__)
3816 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3818 if (SDL_Init (flags)) {
3819 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3820 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3824 if (!display_disable) {
3825 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3826 fs_screen_width = vi->current_w;
3827 fs_screen_height = vi->current_h;
3830 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3831 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3832 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3834 if (av_lockmgr_register(lockmgr)) {
3835 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3839 av_init_packet(&flush_pkt);
3840 flush_pkt.data = (uint8_t *)&flush_pkt;
3842 is = stream_open(input_filename, file_iformat);
3844 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");