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));
1250 if (!s->rdft || !s->rdft_data){
1251 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1252 s->show_mode = SHOW_MODE_WAVES;
1255 for (ch = 0; ch < nb_display_channels; ch++) {
1256 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1258 for (x = 0; x < 2 * nb_freq; x++) {
1259 double w = (x-nb_freq) * (1.0 / nb_freq);
1260 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1262 if (i >= SAMPLE_ARRAY_SIZE)
1263 i -= SAMPLE_ARRAY_SIZE;
1265 av_rdft_calc(s->rdft, data[ch]);
1267 /* Least efficient way to do this, we should of course
1268 * directly access it but it is more than fast enough. */
1269 for (y = 0; y < s->height; y++) {
1270 double w = 1 / sqrt(nb_freq);
1271 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]));
1272 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1273 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1276 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1278 fill_rectangle(screen,
1279 s->xpos, s->height-y, 1, 1,
1283 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1286 if (s->xpos >= s->width)
1291 static void stream_close(VideoState *is)
1293 /* XXX: use a special url_shutdown call to abort parse cleanly */
1294 is->abort_request = 1;
1295 SDL_WaitThread(is->read_tid, NULL);
1296 packet_queue_destroy(&is->videoq);
1297 packet_queue_destroy(&is->audioq);
1298 packet_queue_destroy(&is->subtitleq);
1300 /* free all pictures */
1301 frame_queue_destory(&is->pictq);
1302 frame_queue_destory(&is->sampq);
1303 frame_queue_destory(&is->subpq);
1304 SDL_DestroyCond(is->continue_read_thread);
1305 #if !CONFIG_AVFILTER
1306 sws_freeContext(is->img_convert_ctx);
1311 static void do_exit(VideoState *is)
1316 av_lockmgr_register(NULL);
1319 av_freep(&vfilters_list);
1321 avformat_network_deinit();
1325 av_log(NULL, AV_LOG_QUIET, "%s", "");
1329 static void sigterm_handler(int sig)
1334 static void set_default_window_size(int width, int height, AVRational sar)
1337 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1338 default_width = rect.w;
1339 default_height = rect.h;
1342 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1344 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1347 if (is_full_screen) flags |= SDL_FULLSCREEN;
1348 else flags |= SDL_RESIZABLE;
1350 if (vp && vp->width)
1351 set_default_window_size(vp->width, vp->height, vp->sar);
1353 if (is_full_screen && fs_screen_width) {
1354 w = fs_screen_width;
1355 h = fs_screen_height;
1356 } else if (!is_full_screen && screen_width) {
1363 w = FFMIN(16383, w);
1364 if (screen && is->width == screen->w && screen->w == w
1365 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1367 screen = SDL_SetVideoMode(w, h, 0, flags);
1369 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1373 window_title = input_filename;
1374 SDL_WM_SetCaption(window_title, window_title);
1376 is->width = screen->w;
1377 is->height = screen->h;
1382 /* display the current picture, if any */
1383 static void video_display(VideoState *is)
1386 video_open(is, 0, NULL);
1387 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1388 video_audio_display(is);
1389 else if (is->video_st)
1390 video_image_display(is);
1393 static double get_clock(Clock *c)
1395 if (*c->queue_serial != c->serial)
1400 double time = av_gettime_relative() / 1000000.0;
1401 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1405 static void set_clock_at(Clock *c, double pts, int serial, double time)
1408 c->last_updated = time;
1409 c->pts_drift = c->pts - time;
1413 static void set_clock(Clock *c, double pts, int serial)
1415 double time = av_gettime_relative() / 1000000.0;
1416 set_clock_at(c, pts, serial, time);
1419 static void set_clock_speed(Clock *c, double speed)
1421 set_clock(c, get_clock(c), c->serial);
1425 static void init_clock(Clock *c, int *queue_serial)
1429 c->queue_serial = queue_serial;
1430 set_clock(c, NAN, -1);
1433 static void sync_clock_to_slave(Clock *c, Clock *slave)
1435 double clock = get_clock(c);
1436 double slave_clock = get_clock(slave);
1437 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1438 set_clock(c, slave_clock, slave->serial);
1441 static int get_master_sync_type(VideoState *is) {
1442 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1444 return AV_SYNC_VIDEO_MASTER;
1446 return AV_SYNC_AUDIO_MASTER;
1447 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1449 return AV_SYNC_AUDIO_MASTER;
1451 return AV_SYNC_EXTERNAL_CLOCK;
1453 return AV_SYNC_EXTERNAL_CLOCK;
1457 /* get the current master clock value */
1458 static double get_master_clock(VideoState *is)
1462 switch (get_master_sync_type(is)) {
1463 case AV_SYNC_VIDEO_MASTER:
1464 val = get_clock(&is->vidclk);
1466 case AV_SYNC_AUDIO_MASTER:
1467 val = get_clock(&is->audclk);
1470 val = get_clock(&is->extclk);
1476 static void check_external_clock_speed(VideoState *is) {
1477 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, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1480 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1481 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1482 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1484 double speed = is->extclk.speed;
1486 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1490 /* seek in the stream */
1491 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1493 if (!is->seek_req) {
1496 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1498 is->seek_flags |= AVSEEK_FLAG_BYTE;
1500 SDL_CondSignal(is->continue_read_thread);
1504 /* pause or resume the video */
1505 static void stream_toggle_pause(VideoState *is)
1508 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1509 if (is->read_pause_return != AVERROR(ENOSYS)) {
1510 is->vidclk.paused = 0;
1512 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1514 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1515 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1518 static void toggle_pause(VideoState *is)
1520 stream_toggle_pause(is);
1524 static void step_to_next_frame(VideoState *is)
1526 /* if the stream is paused unpause it, then step */
1528 stream_toggle_pause(is);
1532 static double compute_target_delay(double delay, VideoState *is)
1534 double sync_threshold, diff;
1536 /* update delay to follow master synchronisation source */
1537 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1538 /* if video is slave, we try to correct big delays by
1539 duplicating or deleting a frame */
1540 diff = get_clock(&is->vidclk) - get_master_clock(is);
1542 /* skip or repeat frame. We take into account the
1543 delay to compute the threshold. I still don't know
1544 if it is the best guess */
1545 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1546 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1547 if (diff <= -sync_threshold)
1548 delay = FFMAX(0, delay + diff);
1549 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1550 delay = delay + diff;
1551 else if (diff >= sync_threshold)
1556 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1562 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1563 if (vp->serial == nextvp->serial) {
1564 double duration = nextvp->pts - vp->pts;
1565 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1566 return vp->duration;
1574 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1575 /* update current video pts */
1576 set_clock(&is->vidclk, pts, serial);
1577 sync_clock_to_slave(&is->extclk, &is->vidclk);
1580 /* called to display each frame */
1581 static void video_refresh(void *opaque, double *remaining_time)
1583 VideoState *is = opaque;
1588 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1589 check_external_clock_speed(is);
1591 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1592 time = av_gettime_relative() / 1000000.0;
1593 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1595 is->last_vis_time = time;
1597 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1602 if (is->force_refresh)
1603 redisplay = frame_queue_prev(&is->pictq);
1605 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1606 // nothing to do, no picture to display in the queue
1608 double last_duration, duration, delay;
1611 /* dequeue the picture */
1612 lastvp = frame_queue_peek_last(&is->pictq);
1613 vp = frame_queue_peek(&is->pictq);
1615 if (vp->serial != is->videoq.serial) {
1616 frame_queue_next(&is->pictq);
1621 if (lastvp->serial != vp->serial && !redisplay)
1622 is->frame_timer = av_gettime_relative() / 1000000.0;
1627 /* compute nominal last_duration */
1628 last_duration = vp_duration(is, lastvp, vp);
1632 delay = compute_target_delay(last_duration, is);
1634 time= av_gettime_relative()/1000000.0;
1635 if (time < is->frame_timer + delay && !redisplay) {
1636 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1640 is->frame_timer += delay;
1641 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1642 is->frame_timer = time;
1644 SDL_LockMutex(is->pictq.mutex);
1645 if (!redisplay && !isnan(vp->pts))
1646 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1647 SDL_UnlockMutex(is->pictq.mutex);
1649 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1650 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1651 duration = vp_duration(is, vp, nextvp);
1652 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1654 is->frame_drops_late++;
1655 frame_queue_next(&is->pictq);
1661 if (is->subtitle_st) {
1662 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1663 sp = frame_queue_peek(&is->subpq);
1665 if (frame_queue_nb_remaining(&is->subpq) > 1)
1666 sp2 = frame_queue_peek_next(&is->subpq);
1670 if (sp->serial != is->subtitleq.serial
1671 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1672 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1674 frame_queue_next(&is->subpq);
1682 /* display picture */
1683 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1686 frame_queue_next(&is->pictq);
1688 if (is->step && !is->paused)
1689 stream_toggle_pause(is);
1692 is->force_refresh = 0;
1694 static int64_t last_time;
1696 int aqsize, vqsize, sqsize;
1699 cur_time = av_gettime_relative();
1700 if (!last_time || (cur_time - last_time) >= 30000) {
1705 aqsize = is->audioq.size;
1707 vqsize = is->videoq.size;
1708 if (is->subtitle_st)
1709 sqsize = is->subtitleq.size;
1711 if (is->audio_st && is->video_st)
1712 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1713 else if (is->video_st)
1714 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1715 else if (is->audio_st)
1716 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1717 av_log(NULL, AV_LOG_INFO,
1718 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1719 get_master_clock(is),
1720 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1722 is->frame_drops_early + is->frame_drops_late,
1726 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1727 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1729 last_time = cur_time;
1734 /* allocate a picture (needs to do that in main thread to avoid
1735 potential locking problems */
1736 static void alloc_picture(VideoState *is)
1741 vp = &is->pictq.queue[is->pictq.windex];
1745 video_open(is, 0, vp);
1747 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1750 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1751 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1752 /* SDL allocates a buffer smaller than requested if the video
1753 * overlay hardware is unable to support the requested size. */
1754 av_log(NULL, AV_LOG_FATAL,
1755 "Error: the video system does not support an image\n"
1756 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1757 "to reduce the image size.\n", vp->width, vp->height );
1761 SDL_LockMutex(is->pictq.mutex);
1763 SDL_CondSignal(is->pictq.cond);
1764 SDL_UnlockMutex(is->pictq.mutex);
1767 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1768 int i, width, height;
1770 for (i = 0; i < 3; i++) {
1777 if (bmp->pitches[i] > width) {
1778 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1779 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1785 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1789 #if defined(DEBUG_SYNC) && 0
1790 printf("frame_type=%c pts=%0.3f\n",
1791 av_get_picture_type_char(src_frame->pict_type), pts);
1794 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1797 vp->sar = src_frame->sample_aspect_ratio;
1799 /* alloc or resize hardware picture buffer */
1800 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1801 vp->width != src_frame->width ||
1802 vp->height != src_frame->height) {
1807 vp->width = src_frame->width;
1808 vp->height = src_frame->height;
1810 /* the allocation must be done in the main thread to avoid
1811 locking problems. */
1812 event.type = FF_ALLOC_EVENT;
1813 event.user.data1 = is;
1814 SDL_PushEvent(&event);
1816 /* wait until the picture is allocated */
1817 SDL_LockMutex(is->pictq.mutex);
1818 while (!vp->allocated && !is->videoq.abort_request) {
1819 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1821 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1822 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1823 while (!vp->allocated && !is->abort_request) {
1824 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1827 SDL_UnlockMutex(is->pictq.mutex);
1829 if (is->videoq.abort_request)
1833 /* if the frame is not skipped, then display it */
1835 AVPicture pict = { { 0 } };
1837 /* get a pointer on the bitmap */
1838 SDL_LockYUVOverlay (vp->bmp);
1840 pict.data[0] = vp->bmp->pixels[0];
1841 pict.data[1] = vp->bmp->pixels[2];
1842 pict.data[2] = vp->bmp->pixels[1];
1844 pict.linesize[0] = vp->bmp->pitches[0];
1845 pict.linesize[1] = vp->bmp->pitches[2];
1846 pict.linesize[2] = vp->bmp->pitches[1];
1849 // FIXME use direct rendering
1850 av_picture_copy(&pict, (AVPicture *)src_frame,
1851 src_frame->format, vp->width, vp->height);
1853 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1854 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1855 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1856 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1857 if (!is->img_convert_ctx) {
1858 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1861 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1862 0, vp->height, pict.data, pict.linesize);
1864 /* workaround SDL PITCH_WORKAROUND */
1865 duplicate_right_border_pixels(vp->bmp);
1866 /* update the bitmap content */
1867 SDL_UnlockYUVOverlay(vp->bmp);
1870 vp->duration = duration;
1872 vp->serial = serial;
1874 /* now we can update the picture count */
1875 frame_queue_push(&is->pictq);
1880 static int get_video_frame(VideoState *is, AVFrame *frame)
1884 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1890 if (frame->pts != AV_NOPTS_VALUE)
1891 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1893 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1895 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1896 if (frame->pts != AV_NOPTS_VALUE) {
1897 double diff = dpts - get_master_clock(is);
1898 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1899 diff - is->frame_last_filter_delay < 0 &&
1900 is->viddec.pkt_serial == is->vidclk.serial &&
1901 is->videoq.nb_packets) {
1902 is->frame_drops_early++;
1903 av_frame_unref(frame);
1914 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1915 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1918 int nb_filters = graph->nb_filters;
1919 AVFilterInOut *outputs = NULL, *inputs = NULL;
1922 outputs = avfilter_inout_alloc();
1923 inputs = avfilter_inout_alloc();
1924 if (!outputs || !inputs) {
1925 ret = AVERROR(ENOMEM);
1929 outputs->name = av_strdup("in");
1930 outputs->filter_ctx = source_ctx;
1931 outputs->pad_idx = 0;
1932 outputs->next = NULL;
1934 inputs->name = av_strdup("out");
1935 inputs->filter_ctx = sink_ctx;
1936 inputs->pad_idx = 0;
1937 inputs->next = NULL;
1939 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1942 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1946 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1947 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1948 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1950 ret = avfilter_graph_config(graph, NULL);
1952 avfilter_inout_free(&outputs);
1953 avfilter_inout_free(&inputs);
1957 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1959 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1960 char sws_flags_str[128];
1961 char buffersrc_args[256];
1963 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1964 AVCodecContext *codec = is->video_st->codec;
1965 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1967 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1968 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1969 graph->scale_sws_opts = av_strdup(sws_flags_str);
1971 snprintf(buffersrc_args, sizeof(buffersrc_args),
1972 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1973 frame->width, frame->height, frame->format,
1974 is->video_st->time_base.num, is->video_st->time_base.den,
1975 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1976 if (fr.num && fr.den)
1977 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1979 if ((ret = avfilter_graph_create_filter(&filt_src,
1980 avfilter_get_by_name("buffer"),
1981 "ffplay_buffer", buffersrc_args, NULL,
1985 ret = avfilter_graph_create_filter(&filt_out,
1986 avfilter_get_by_name("buffersink"),
1987 "ffplay_buffersink", NULL, NULL, graph);
1991 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1994 last_filter = filt_out;
1996 /* Note: this macro adds a filter before the lastly added filter, so the
1997 * processing order of the filters is in reverse */
1998 #define INSERT_FILT(name, arg) do { \
1999 AVFilterContext *filt_ctx; \
2001 ret = avfilter_graph_create_filter(&filt_ctx, \
2002 avfilter_get_by_name(name), \
2003 "ffplay_" name, arg, NULL, graph); \
2007 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
2011 last_filter = filt_ctx; \
2014 /* SDL YUV code is not handling odd width/height for some driver
2015 * combinations, therefore we crop the picture to an even width/height. */
2016 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
2019 AVDictionaryEntry *rotate_tag = av_dict_get(is->video_st->metadata, "rotate", NULL, 0);
2020 if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
2021 if (!strcmp(rotate_tag->value, "90")) {
2022 INSERT_FILT("transpose", "clock");
2023 } else if (!strcmp(rotate_tag->value, "180")) {
2024 INSERT_FILT("hflip", NULL);
2025 INSERT_FILT("vflip", NULL);
2026 } else if (!strcmp(rotate_tag->value, "270")) {
2027 INSERT_FILT("transpose", "cclock");
2029 char rotate_buf[64];
2030 snprintf(rotate_buf, sizeof(rotate_buf), "%s*PI/180", rotate_tag->value);
2031 INSERT_FILT("rotate", rotate_buf);
2036 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
2039 is->in_video_filter = filt_src;
2040 is->out_video_filter = filt_out;
2046 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
2048 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2049 int sample_rates[2] = { 0, -1 };
2050 int64_t channel_layouts[2] = { 0, -1 };
2051 int channels[2] = { 0, -1 };
2052 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2053 char aresample_swr_opts[512] = "";
2054 AVDictionaryEntry *e = NULL;
2055 char asrc_args[256];
2058 avfilter_graph_free(&is->agraph);
2059 if (!(is->agraph = avfilter_graph_alloc()))
2060 return AVERROR(ENOMEM);
2062 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2063 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2064 if (strlen(aresample_swr_opts))
2065 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2066 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2068 ret = snprintf(asrc_args, sizeof(asrc_args),
2069 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2070 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2071 is->audio_filter_src.channels,
2072 1, is->audio_filter_src.freq);
2073 if (is->audio_filter_src.channel_layout)
2074 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2075 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2077 ret = avfilter_graph_create_filter(&filt_asrc,
2078 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2079 asrc_args, NULL, is->agraph);
2084 ret = avfilter_graph_create_filter(&filt_asink,
2085 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2086 NULL, NULL, is->agraph);
2090 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2092 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2095 if (force_output_format) {
2096 channel_layouts[0] = is->audio_tgt.channel_layout;
2097 channels [0] = is->audio_tgt.channels;
2098 sample_rates [0] = is->audio_tgt.freq;
2099 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2101 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2103 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2105 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2110 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2113 is->in_audio_filter = filt_asrc;
2114 is->out_audio_filter = filt_asink;
2118 avfilter_graph_free(&is->agraph);
2121 #endif /* CONFIG_AVFILTER */
2123 static int audio_thread(void *arg)
2125 VideoState *is = arg;
2126 AVFrame *frame = av_frame_alloc();
2129 int last_serial = -1;
2130 int64_t dec_channel_layout;
2138 return AVERROR(ENOMEM);
2141 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2145 tb = (AVRational){1, frame->sample_rate};
2148 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2151 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2152 frame->format, av_frame_get_channels(frame)) ||
2153 is->audio_filter_src.channel_layout != dec_channel_layout ||
2154 is->audio_filter_src.freq != frame->sample_rate ||
2155 is->auddec.pkt_serial != last_serial;
2158 char buf1[1024], buf2[1024];
2159 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2160 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2161 av_log(NULL, AV_LOG_DEBUG,
2162 "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",
2163 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2164 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2166 is->audio_filter_src.fmt = frame->format;
2167 is->audio_filter_src.channels = av_frame_get_channels(frame);
2168 is->audio_filter_src.channel_layout = dec_channel_layout;
2169 is->audio_filter_src.freq = frame->sample_rate;
2170 last_serial = is->auddec.pkt_serial;
2172 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2176 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2179 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2180 tb = is->out_audio_filter->inputs[0]->time_base;
2182 if (!(af = frame_queue_peek_writable(&is->sampq)))
2185 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2186 af->pos = av_frame_get_pkt_pos(frame);
2187 af->serial = is->auddec.pkt_serial;
2188 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2190 av_frame_move_ref(af->frame, frame);
2191 frame_queue_push(&is->sampq);
2194 if (is->audioq.serial != is->auddec.pkt_serial)
2197 if (ret == AVERROR_EOF)
2198 is->auddec.finished = is->auddec.pkt_serial;
2201 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2204 avfilter_graph_free(&is->agraph);
2206 av_frame_free(&frame);
2210 static void decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2212 packet_queue_start(d->queue);
2213 d->decoder_tid = SDL_CreateThread(fn, arg);
2216 static int video_thread(void *arg)
2218 VideoState *is = arg;
2219 AVFrame *frame = av_frame_alloc();
2223 AVRational tb = is->video_st->time_base;
2224 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2227 AVFilterGraph *graph = avfilter_graph_alloc();
2228 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2231 enum AVPixelFormat last_format = -2;
2232 int last_serial = -1;
2233 int last_vfilter_idx = 0;
2235 av_frame_free(&frame);
2236 return AVERROR(ENOMEM);
2243 avfilter_graph_free(&graph);
2245 return AVERROR(ENOMEM);
2249 ret = get_video_frame(is, frame);
2256 if ( last_w != frame->width
2257 || last_h != frame->height
2258 || last_format != frame->format
2259 || last_serial != is->viddec.pkt_serial
2260 || last_vfilter_idx != is->vfilter_idx) {
2261 av_log(NULL, AV_LOG_DEBUG,
2262 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2264 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2265 frame->width, frame->height,
2266 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2267 avfilter_graph_free(&graph);
2268 graph = avfilter_graph_alloc();
2269 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2271 event.type = FF_QUIT_EVENT;
2272 event.user.data1 = is;
2273 SDL_PushEvent(&event);
2276 filt_in = is->in_video_filter;
2277 filt_out = is->out_video_filter;
2278 last_w = frame->width;
2279 last_h = frame->height;
2280 last_format = frame->format;
2281 last_serial = is->viddec.pkt_serial;
2282 last_vfilter_idx = is->vfilter_idx;
2283 frame_rate = filt_out->inputs[0]->frame_rate;
2286 ret = av_buffersrc_add_frame(filt_in, frame);
2291 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2293 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2295 if (ret == AVERROR_EOF)
2296 is->viddec.finished = is->viddec.pkt_serial;
2301 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2302 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2303 is->frame_last_filter_delay = 0;
2304 tb = filt_out->inputs[0]->time_base;
2306 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2307 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2308 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2309 av_frame_unref(frame);
2319 avfilter_graph_free(&graph);
2321 av_frame_free(&frame);
2325 static int subtitle_thread(void *arg)
2327 VideoState *is = arg;
2332 int r, g, b, y, u, v, a;
2335 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2338 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2343 if (got_subtitle && sp->sub.format == 0) {
2344 if (sp->sub.pts != AV_NOPTS_VALUE)
2345 pts = sp->sub.pts / (double)AV_TIME_BASE;
2347 sp->serial = is->subdec.pkt_serial;
2349 for (i = 0; i < sp->sub.num_rects; i++)
2351 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2353 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2354 y = RGB_TO_Y_CCIR(r, g, b);
2355 u = RGB_TO_U_CCIR(r, g, b, 0);
2356 v = RGB_TO_V_CCIR(r, g, b, 0);
2357 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2361 /* now we can update the picture count */
2362 frame_queue_push(&is->subpq);
2363 } else if (got_subtitle) {
2364 avsubtitle_free(&sp->sub);
2370 /* copy samples for viewing in editor window */
2371 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2375 size = samples_size / sizeof(short);
2377 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2380 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2382 is->sample_array_index += len;
2383 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2384 is->sample_array_index = 0;
2389 /* return the wanted number of samples to get better sync if sync_type is video
2390 * or external master clock */
2391 static int synchronize_audio(VideoState *is, int nb_samples)
2393 int wanted_nb_samples = nb_samples;
2395 /* if not master, then we try to remove or add samples to correct the clock */
2396 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2397 double diff, avg_diff;
2398 int min_nb_samples, max_nb_samples;
2400 diff = get_clock(&is->audclk) - get_master_clock(is);
2402 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2403 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2404 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2405 /* not enough measures to have a correct estimate */
2406 is->audio_diff_avg_count++;
2408 /* estimate the A-V difference */
2409 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2411 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2412 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2413 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2414 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2415 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2417 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2418 diff, avg_diff, wanted_nb_samples - nb_samples,
2419 is->audio_clock, is->audio_diff_threshold);
2422 /* too big difference : may be initial PTS errors, so
2424 is->audio_diff_avg_count = 0;
2425 is->audio_diff_cum = 0;
2429 return wanted_nb_samples;
2433 * Decode one audio frame and return its uncompressed size.
2435 * The processed audio frame is decoded, converted if required, and
2436 * stored in is->audio_buf, with size in bytes given by the return
2439 static int audio_decode_frame(VideoState *is)
2441 int data_size, resampled_data_size;
2442 int64_t dec_channel_layout;
2443 av_unused double audio_clock0;
2444 int wanted_nb_samples;
2451 if (!(af = frame_queue_peek_readable(&is->sampq)))
2453 frame_queue_next(&is->sampq);
2454 } while (af->serial != is->audioq.serial);
2456 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2457 af->frame->nb_samples,
2458 af->frame->format, 1);
2460 dec_channel_layout =
2461 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2462 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2463 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2465 if (af->frame->format != is->audio_src.fmt ||
2466 dec_channel_layout != is->audio_src.channel_layout ||
2467 af->frame->sample_rate != is->audio_src.freq ||
2468 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2469 swr_free(&is->swr_ctx);
2470 is->swr_ctx = swr_alloc_set_opts(NULL,
2471 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2472 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2474 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2475 av_log(NULL, AV_LOG_ERROR,
2476 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2477 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2478 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2479 swr_free(&is->swr_ctx);
2482 is->audio_src.channel_layout = dec_channel_layout;
2483 is->audio_src.channels = av_frame_get_channels(af->frame);
2484 is->audio_src.freq = af->frame->sample_rate;
2485 is->audio_src.fmt = af->frame->format;
2489 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2490 uint8_t **out = &is->audio_buf1;
2491 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2492 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2495 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2498 if (wanted_nb_samples != af->frame->nb_samples) {
2499 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2500 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2501 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2505 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2506 if (!is->audio_buf1)
2507 return AVERROR(ENOMEM);
2508 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2510 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2513 if (len2 == out_count) {
2514 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2515 if (swr_init(is->swr_ctx) < 0)
2516 swr_free(&is->swr_ctx);
2518 is->audio_buf = is->audio_buf1;
2519 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2521 is->audio_buf = af->frame->data[0];
2522 resampled_data_size = data_size;
2525 audio_clock0 = is->audio_clock;
2526 /* update the audio clock with the pts */
2527 if (!isnan(af->pts))
2528 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2530 is->audio_clock = NAN;
2531 is->audio_clock_serial = af->serial;
2534 static double last_clock;
2535 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2536 is->audio_clock - last_clock,
2537 is->audio_clock, audio_clock0);
2538 last_clock = is->audio_clock;
2541 return resampled_data_size;
2544 /* prepare a new audio buffer */
2545 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2547 VideoState *is = opaque;
2548 int audio_size, len1;
2550 audio_callback_time = av_gettime_relative();
2553 if (is->audio_buf_index >= is->audio_buf_size) {
2554 audio_size = audio_decode_frame(is);
2555 if (audio_size < 0) {
2556 /* if error, just output silence */
2557 is->audio_buf = is->silence_buf;
2558 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2560 if (is->show_mode != SHOW_MODE_VIDEO)
2561 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2562 is->audio_buf_size = audio_size;
2564 is->audio_buf_index = 0;
2566 len1 = is->audio_buf_size - is->audio_buf_index;
2569 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2572 is->audio_buf_index += len1;
2574 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2575 /* Let's assume the audio driver that is used by SDL has two periods. */
2576 if (!isnan(is->audio_clock)) {
2577 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);
2578 sync_clock_to_slave(&is->extclk, &is->audclk);
2582 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2584 SDL_AudioSpec wanted_spec, spec;
2586 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2587 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2588 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2590 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2592 wanted_nb_channels = atoi(env);
2593 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2595 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2596 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2597 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2599 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2600 wanted_spec.channels = wanted_nb_channels;
2601 wanted_spec.freq = wanted_sample_rate;
2602 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2603 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2606 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2607 next_sample_rate_idx--;
2608 wanted_spec.format = AUDIO_S16SYS;
2609 wanted_spec.silence = 0;
2610 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2611 wanted_spec.callback = sdl_audio_callback;
2612 wanted_spec.userdata = opaque;
2613 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2614 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2615 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2616 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2617 if (!wanted_spec.channels) {
2618 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2619 wanted_spec.channels = wanted_nb_channels;
2620 if (!wanted_spec.freq) {
2621 av_log(NULL, AV_LOG_ERROR,
2622 "No more combinations to try, audio open failed\n");
2626 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2628 if (spec.format != AUDIO_S16SYS) {
2629 av_log(NULL, AV_LOG_ERROR,
2630 "SDL advised audio format %d is not supported!\n", spec.format);
2633 if (spec.channels != wanted_spec.channels) {
2634 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2635 if (!wanted_channel_layout) {
2636 av_log(NULL, AV_LOG_ERROR,
2637 "SDL advised channel count %d is not supported!\n", spec.channels);
2642 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2643 audio_hw_params->freq = spec.freq;
2644 audio_hw_params->channel_layout = wanted_channel_layout;
2645 audio_hw_params->channels = spec.channels;
2646 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2647 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);
2648 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2649 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2655 /* open a given stream. Return 0 if OK */
2656 static int stream_component_open(VideoState *is, int stream_index)
2658 AVFormatContext *ic = is->ic;
2659 AVCodecContext *avctx;
2661 const char *forced_codec_name = NULL;
2663 AVDictionaryEntry *t = NULL;
2664 int sample_rate, nb_channels;
2665 int64_t channel_layout;
2667 int stream_lowres = lowres;
2669 if (stream_index < 0 || stream_index >= ic->nb_streams)
2671 avctx = ic->streams[stream_index]->codec;
2673 codec = avcodec_find_decoder(avctx->codec_id);
2675 switch(avctx->codec_type){
2676 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2677 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2678 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2680 if (forced_codec_name)
2681 codec = avcodec_find_decoder_by_name(forced_codec_name);
2683 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2684 "No codec could be found with name '%s'\n", forced_codec_name);
2685 else av_log(NULL, AV_LOG_WARNING,
2686 "No codec could be found with id %d\n", avctx->codec_id);
2690 avctx->codec_id = codec->id;
2691 if(stream_lowres > av_codec_get_max_lowres(codec)){
2692 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2693 av_codec_get_max_lowres(codec));
2694 stream_lowres = av_codec_get_max_lowres(codec);
2696 av_codec_set_lowres(avctx, stream_lowres);
2698 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2699 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2700 if(codec->capabilities & CODEC_CAP_DR1)
2701 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2703 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2704 if (!av_dict_get(opts, "threads", NULL, 0))
2705 av_dict_set(&opts, "threads", "auto", 0);
2707 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2708 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2709 av_dict_set(&opts, "refcounted_frames", "1", 0);
2710 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2713 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2714 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2715 ret = AVERROR_OPTION_NOT_FOUND;
2720 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2721 switch (avctx->codec_type) {
2722 case AVMEDIA_TYPE_AUDIO:
2727 is->audio_filter_src.freq = avctx->sample_rate;
2728 is->audio_filter_src.channels = avctx->channels;
2729 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2730 is->audio_filter_src.fmt = avctx->sample_fmt;
2731 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2733 link = is->out_audio_filter->inputs[0];
2734 sample_rate = link->sample_rate;
2735 nb_channels = link->channels;
2736 channel_layout = link->channel_layout;
2739 sample_rate = avctx->sample_rate;
2740 nb_channels = avctx->channels;
2741 channel_layout = avctx->channel_layout;
2744 /* prepare audio output */
2745 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2747 is->audio_hw_buf_size = ret;
2748 is->audio_src = is->audio_tgt;
2749 is->audio_buf_size = 0;
2750 is->audio_buf_index = 0;
2752 /* init averaging filter */
2753 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2754 is->audio_diff_avg_count = 0;
2755 /* since we do not have a precise anough audio fifo fullness,
2756 we correct audio sync only if larger than this threshold */
2757 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2759 is->audio_stream = stream_index;
2760 is->audio_st = ic->streams[stream_index];
2762 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2763 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2764 is->auddec.start_pts = is->audio_st->start_time;
2765 is->auddec.start_pts_tb = is->audio_st->time_base;
2767 decoder_start(&is->auddec, audio_thread, is);
2770 case AVMEDIA_TYPE_VIDEO:
2771 is->video_stream = stream_index;
2772 is->video_st = ic->streams[stream_index];
2774 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2775 decoder_start(&is->viddec, video_thread, is);
2776 is->queue_attachments_req = 1;
2778 case AVMEDIA_TYPE_SUBTITLE:
2779 is->subtitle_stream = stream_index;
2780 is->subtitle_st = ic->streams[stream_index];
2782 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2783 decoder_start(&is->subdec, subtitle_thread, is);
2790 av_dict_free(&opts);
2795 static void stream_component_close(VideoState *is, int stream_index)
2797 AVFormatContext *ic = is->ic;
2798 AVCodecContext *avctx;
2800 if (stream_index < 0 || stream_index >= ic->nb_streams)
2802 avctx = ic->streams[stream_index]->codec;
2804 switch (avctx->codec_type) {
2805 case AVMEDIA_TYPE_AUDIO:
2806 decoder_abort(&is->auddec, &is->sampq);
2808 decoder_destroy(&is->auddec);
2809 swr_free(&is->swr_ctx);
2810 av_freep(&is->audio_buf1);
2811 is->audio_buf1_size = 0;
2812 is->audio_buf = NULL;
2815 av_rdft_end(is->rdft);
2816 av_freep(&is->rdft_data);
2821 case AVMEDIA_TYPE_VIDEO:
2822 decoder_abort(&is->viddec, &is->pictq);
2823 decoder_destroy(&is->viddec);
2825 case AVMEDIA_TYPE_SUBTITLE:
2826 decoder_abort(&is->subdec, &is->subpq);
2827 decoder_destroy(&is->subdec);
2833 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2834 avcodec_close(avctx);
2835 switch (avctx->codec_type) {
2836 case AVMEDIA_TYPE_AUDIO:
2837 is->audio_st = NULL;
2838 is->audio_stream = -1;
2840 case AVMEDIA_TYPE_VIDEO:
2841 is->video_st = NULL;
2842 is->video_stream = -1;
2844 case AVMEDIA_TYPE_SUBTITLE:
2845 is->subtitle_st = NULL;
2846 is->subtitle_stream = -1;
2853 static int decode_interrupt_cb(void *ctx)
2855 VideoState *is = ctx;
2856 return is->abort_request;
2859 static int is_realtime(AVFormatContext *s)
2861 if( !strcmp(s->iformat->name, "rtp")
2862 || !strcmp(s->iformat->name, "rtsp")
2863 || !strcmp(s->iformat->name, "sdp")
2867 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2868 || !strncmp(s->filename, "udp:", 4)
2875 /* this thread gets the stream from the disk or the network */
2876 static int read_thread(void *arg)
2878 VideoState *is = arg;
2879 AVFormatContext *ic = NULL;
2881 int st_index[AVMEDIA_TYPE_NB];
2882 AVPacket pkt1, *pkt = &pkt1;
2883 int64_t stream_start_time;
2884 int pkt_in_play_range = 0;
2885 AVDictionaryEntry *t;
2886 AVDictionary **opts;
2887 int orig_nb_streams;
2888 SDL_mutex *wait_mutex = SDL_CreateMutex();
2889 int scan_all_pmts_set = 0;
2892 memset(st_index, -1, sizeof(st_index));
2893 is->last_video_stream = is->video_stream = -1;
2894 is->last_audio_stream = is->audio_stream = -1;
2895 is->last_subtitle_stream = is->subtitle_stream = -1;
2898 ic = avformat_alloc_context();
2900 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2901 ret = AVERROR(ENOMEM);
2904 ic->interrupt_callback.callback = decode_interrupt_cb;
2905 ic->interrupt_callback.opaque = is;
2906 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2907 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2908 scan_all_pmts_set = 1;
2910 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2912 print_error(is->filename, err);
2916 if (scan_all_pmts_set)
2917 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2919 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2920 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2921 ret = AVERROR_OPTION_NOT_FOUND;
2927 ic->flags |= AVFMT_FLAG_GENPTS;
2929 av_format_inject_global_side_data(ic);
2931 opts = setup_find_stream_info_opts(ic, codec_opts);
2932 orig_nb_streams = ic->nb_streams;
2934 err = avformat_find_stream_info(ic, opts);
2936 for (i = 0; i < orig_nb_streams; i++)
2937 av_dict_free(&opts[i]);
2941 av_log(NULL, AV_LOG_WARNING,
2942 "%s: could not find codec parameters\n", is->filename);
2948 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2950 if (seek_by_bytes < 0)
2951 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2953 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2955 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2956 window_title = av_asprintf("%s - %s", t->value, input_filename);
2958 /* if seeking requested, we execute it */
2959 if (start_time != AV_NOPTS_VALUE) {
2962 timestamp = start_time;
2963 /* add the stream start time */
2964 if (ic->start_time != AV_NOPTS_VALUE)
2965 timestamp += ic->start_time;
2966 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2968 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2969 is->filename, (double)timestamp / AV_TIME_BASE);
2973 is->realtime = is_realtime(ic);
2976 av_dump_format(ic, 0, is->filename, 0);
2978 for (i = 0; i < ic->nb_streams; i++) {
2979 AVStream *st = ic->streams[i];
2980 enum AVMediaType type = st->codec->codec_type;
2981 st->discard = AVDISCARD_ALL;
2982 if (wanted_stream_spec[type] && st_index[type] == -1)
2983 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2986 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2987 if (wanted_stream_spec[i] && st_index[i] == -1) {
2988 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));
2989 st_index[i] = INT_MAX;
2994 st_index[AVMEDIA_TYPE_VIDEO] =
2995 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2996 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2998 st_index[AVMEDIA_TYPE_AUDIO] =
2999 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
3000 st_index[AVMEDIA_TYPE_AUDIO],
3001 st_index[AVMEDIA_TYPE_VIDEO],
3003 if (!video_disable && !subtitle_disable)
3004 st_index[AVMEDIA_TYPE_SUBTITLE] =
3005 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
3006 st_index[AVMEDIA_TYPE_SUBTITLE],
3007 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
3008 st_index[AVMEDIA_TYPE_AUDIO] :
3009 st_index[AVMEDIA_TYPE_VIDEO]),
3012 is->show_mode = show_mode;
3013 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3014 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
3015 AVCodecContext *avctx = st->codec;
3016 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
3018 set_default_window_size(avctx->width, avctx->height, sar);
3021 /* open the streams */
3022 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
3023 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
3027 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3028 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
3030 if (is->show_mode == SHOW_MODE_NONE)
3031 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
3033 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
3034 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
3037 if (is->video_stream < 0 && is->audio_stream < 0) {
3038 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
3044 if (infinite_buffer < 0 && is->realtime)
3045 infinite_buffer = 1;
3048 if (is->abort_request)
3050 if (is->paused != is->last_paused) {
3051 is->last_paused = is->paused;
3053 is->read_pause_return = av_read_pause(ic);
3057 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3059 (!strcmp(ic->iformat->name, "rtsp") ||
3060 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3061 /* wait 10 ms to avoid trying to get another packet */
3068 int64_t seek_target = is->seek_pos;
3069 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3070 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3071 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3072 // of the seek_pos/seek_rel variables
3074 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3076 av_log(NULL, AV_LOG_ERROR,
3077 "%s: error while seeking\n", is->ic->filename);
3079 if (is->audio_stream >= 0) {
3080 packet_queue_flush(&is->audioq);
3081 packet_queue_put(&is->audioq, &flush_pkt);
3083 if (is->subtitle_stream >= 0) {
3084 packet_queue_flush(&is->subtitleq);
3085 packet_queue_put(&is->subtitleq, &flush_pkt);
3087 if (is->video_stream >= 0) {
3088 packet_queue_flush(&is->videoq);
3089 packet_queue_put(&is->videoq, &flush_pkt);
3091 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3092 set_clock(&is->extclk, NAN, 0);
3094 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3098 is->queue_attachments_req = 1;
3101 step_to_next_frame(is);
3103 if (is->queue_attachments_req) {
3104 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3106 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3108 packet_queue_put(&is->videoq, ©);
3109 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3111 is->queue_attachments_req = 0;
3114 /* if the queue are full, no need to read more */
3115 if (infinite_buffer<1 &&
3116 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3117 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3118 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3119 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3120 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3122 SDL_LockMutex(wait_mutex);
3123 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3124 SDL_UnlockMutex(wait_mutex);
3128 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3129 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3130 if (loop != 1 && (!loop || --loop)) {
3131 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3132 } else if (autoexit) {
3137 ret = av_read_frame(ic, pkt);
3139 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3140 if (is->video_stream >= 0)
3141 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3142 if (is->audio_stream >= 0)
3143 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3144 if (is->subtitle_stream >= 0)
3145 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3148 if (ic->pb && ic->pb->error)
3150 SDL_LockMutex(wait_mutex);
3151 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3152 SDL_UnlockMutex(wait_mutex);
3157 /* check if packet is in play range specified by user, then queue, otherwise discard */
3158 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3159 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3160 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3161 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3162 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3163 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3164 <= ((double)duration / 1000000);
3165 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3166 packet_queue_put(&is->audioq, pkt);
3167 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3168 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3169 packet_queue_put(&is->videoq, pkt);
3170 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3171 packet_queue_put(&is->subtitleq, pkt);
3173 av_free_packet(pkt);
3176 /* wait until the end */
3177 while (!is->abort_request) {
3183 /* close each stream */
3184 if (is->audio_stream >= 0)
3185 stream_component_close(is, is->audio_stream);
3186 if (is->video_stream >= 0)
3187 stream_component_close(is, is->video_stream);
3188 if (is->subtitle_stream >= 0)
3189 stream_component_close(is, is->subtitle_stream);
3191 avformat_close_input(&ic);
3198 event.type = FF_QUIT_EVENT;
3199 event.user.data1 = is;
3200 SDL_PushEvent(&event);
3202 SDL_DestroyMutex(wait_mutex);
3206 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3210 is = av_mallocz(sizeof(VideoState));
3213 av_strlcpy(is->filename, filename, sizeof(is->filename));
3214 is->iformat = iformat;
3218 /* start video display */
3219 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3221 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3223 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3226 packet_queue_init(&is->videoq);
3227 packet_queue_init(&is->audioq);
3228 packet_queue_init(&is->subtitleq);
3230 is->continue_read_thread = SDL_CreateCond();
3232 init_clock(&is->vidclk, &is->videoq.serial);
3233 init_clock(&is->audclk, &is->audioq.serial);
3234 init_clock(&is->extclk, &is->extclk.serial);
3235 is->audio_clock_serial = -1;
3236 is->av_sync_type = av_sync_type;
3237 is->read_tid = SDL_CreateThread(read_thread, is);
3238 if (!is->read_tid) {
3246 static void stream_cycle_channel(VideoState *is, int codec_type)
3248 AVFormatContext *ic = is->ic;
3249 int start_index, stream_index;
3252 AVProgram *p = NULL;
3253 int nb_streams = is->ic->nb_streams;
3255 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3256 start_index = is->last_video_stream;
3257 old_index = is->video_stream;
3258 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3259 start_index = is->last_audio_stream;
3260 old_index = is->audio_stream;
3262 start_index = is->last_subtitle_stream;
3263 old_index = is->subtitle_stream;
3265 stream_index = start_index;
3267 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3268 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3270 nb_streams = p->nb_stream_indexes;
3271 for (start_index = 0; start_index < nb_streams; start_index++)
3272 if (p->stream_index[start_index] == stream_index)
3274 if (start_index == nb_streams)
3276 stream_index = start_index;
3281 if (++stream_index >= nb_streams)
3283 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3286 is->last_subtitle_stream = -1;
3289 if (start_index == -1)
3293 if (stream_index == start_index)
3295 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3296 if (st->codec->codec_type == codec_type) {
3297 /* check that parameters are OK */
3298 switch (codec_type) {
3299 case AVMEDIA_TYPE_AUDIO:
3300 if (st->codec->sample_rate != 0 &&
3301 st->codec->channels != 0)
3304 case AVMEDIA_TYPE_VIDEO:
3305 case AVMEDIA_TYPE_SUBTITLE:
3313 if (p && stream_index != -1)
3314 stream_index = p->stream_index[stream_index];
3315 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3316 av_get_media_type_string(codec_type),
3320 stream_component_close(is, old_index);
3321 stream_component_open(is, stream_index);
3325 static void toggle_full_screen(VideoState *is)
3327 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3328 /* OS X needs to reallocate the SDL overlays */
3330 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3331 is->pictq.queue[i].reallocate = 1;
3333 is_full_screen = !is_full_screen;
3334 video_open(is, 1, NULL);
3337 static void toggle_audio_display(VideoState *is)
3339 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3340 int next = is->show_mode;
3342 next = (next + 1) % SHOW_MODE_NB;
3343 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3344 if (is->show_mode != next) {
3345 fill_rectangle(screen,
3346 is->xleft, is->ytop, is->width, is->height,
3348 is->force_refresh = 1;
3349 is->show_mode = next;
3353 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3354 double remaining_time = 0.0;
3356 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3357 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3361 if (remaining_time > 0.0)
3362 av_usleep((int64_t)(remaining_time * 1000000.0));
3363 remaining_time = REFRESH_RATE;
3364 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3365 video_refresh(is, &remaining_time);
3370 static void seek_chapter(VideoState *is, int incr)
3372 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3375 if (!is->ic->nb_chapters)
3378 /* find the current chapter */
3379 for (i = 0; i < is->ic->nb_chapters; i++) {
3380 AVChapter *ch = is->ic->chapters[i];
3381 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3389 if (i >= is->ic->nb_chapters)
3392 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3393 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3394 AV_TIME_BASE_Q), 0, 0);
3397 /* handle an event sent by the GUI */
3398 static void event_loop(VideoState *cur_stream)
3401 double incr, pos, frac;
3405 refresh_loop_wait_event(cur_stream, &event);
3406 switch (event.type) {
3408 if (exit_on_keydown) {
3409 do_exit(cur_stream);
3412 switch (event.key.keysym.sym) {
3415 do_exit(cur_stream);
3418 toggle_full_screen(cur_stream);
3419 cur_stream->force_refresh = 1;
3423 toggle_pause(cur_stream);
3425 case SDLK_s: // S: Step to next frame
3426 step_to_next_frame(cur_stream);
3429 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3432 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3435 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3436 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3437 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3440 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3444 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3445 if (++cur_stream->vfilter_idx >= nb_vfilters)
3446 cur_stream->vfilter_idx = 0;
3448 cur_stream->vfilter_idx = 0;
3449 toggle_audio_display(cur_stream);
3452 toggle_audio_display(cur_stream);
3456 if (cur_stream->ic->nb_chapters <= 1) {
3460 seek_chapter(cur_stream, 1);
3463 if (cur_stream->ic->nb_chapters <= 1) {
3467 seek_chapter(cur_stream, -1);
3481 if (seek_by_bytes) {
3483 if (pos < 0 && cur_stream->video_stream >= 0)
3484 pos = frame_queue_last_pos(&cur_stream->pictq);
3485 if (pos < 0 && cur_stream->audio_stream >= 0)
3486 pos = frame_queue_last_pos(&cur_stream->sampq);
3488 pos = avio_tell(cur_stream->ic->pb);
3489 if (cur_stream->ic->bit_rate)
3490 incr *= cur_stream->ic->bit_rate / 8.0;
3494 stream_seek(cur_stream, pos, incr, 1);
3496 pos = get_master_clock(cur_stream);
3498 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3500 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3501 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3502 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3509 case SDL_VIDEOEXPOSE:
3510 cur_stream->force_refresh = 1;
3512 case SDL_MOUSEBUTTONDOWN:
3513 if (exit_on_mousedown) {
3514 do_exit(cur_stream);
3517 case SDL_MOUSEMOTION:
3518 if (cursor_hidden) {
3522 cursor_last_shown = av_gettime_relative();
3523 if (event.type == SDL_MOUSEBUTTONDOWN) {
3526 if (event.motion.state != SDL_PRESSED)
3530 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3531 uint64_t size = avio_size(cur_stream->ic->pb);
3532 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3536 int tns, thh, tmm, tss;
3537 tns = cur_stream->ic->duration / 1000000LL;
3539 tmm = (tns % 3600) / 60;
3541 frac = x / cur_stream->width;
3544 mm = (ns % 3600) / 60;
3546 av_log(NULL, AV_LOG_INFO,
3547 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3548 hh, mm, ss, thh, tmm, tss);
3549 ts = frac * cur_stream->ic->duration;
3550 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3551 ts += cur_stream->ic->start_time;
3552 stream_seek(cur_stream, ts, 0, 0);
3555 case SDL_VIDEORESIZE:
3556 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3557 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3559 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3560 do_exit(cur_stream);
3562 screen_width = cur_stream->width = screen->w;
3563 screen_height = cur_stream->height = screen->h;
3564 cur_stream->force_refresh = 1;
3568 do_exit(cur_stream);
3570 case FF_ALLOC_EVENT:
3571 alloc_picture(event.user.data1);
3579 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3581 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3582 return opt_default(NULL, "video_size", arg);
3585 static int opt_width(void *optctx, const char *opt, const char *arg)
3587 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3591 static int opt_height(void *optctx, const char *opt, const char *arg)
3593 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3597 static int opt_format(void *optctx, const char *opt, const char *arg)
3599 file_iformat = av_find_input_format(arg);
3600 if (!file_iformat) {
3601 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3602 return AVERROR(EINVAL);
3607 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3609 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3610 return opt_default(NULL, "pixel_format", arg);
3613 static int opt_sync(void *optctx, const char *opt, const char *arg)
3615 if (!strcmp(arg, "audio"))
3616 av_sync_type = AV_SYNC_AUDIO_MASTER;
3617 else if (!strcmp(arg, "video"))
3618 av_sync_type = AV_SYNC_VIDEO_MASTER;
3619 else if (!strcmp(arg, "ext"))
3620 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3622 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3628 static int opt_seek(void *optctx, const char *opt, const char *arg)
3630 start_time = parse_time_or_die(opt, arg, 1);
3634 static int opt_duration(void *optctx, const char *opt, const char *arg)
3636 duration = parse_time_or_die(opt, arg, 1);
3640 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3642 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3643 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3644 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3645 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3649 static void opt_input_file(void *optctx, const char *filename)
3651 if (input_filename) {
3652 av_log(NULL, AV_LOG_FATAL,
3653 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3654 filename, input_filename);
3657 if (!strcmp(filename, "-"))
3659 input_filename = filename;
3662 static int opt_codec(void *optctx, const char *opt, const char *arg)
3664 const char *spec = strchr(opt, ':');
3666 av_log(NULL, AV_LOG_ERROR,
3667 "No media specifier was specified in '%s' in option '%s'\n",
3669 return AVERROR(EINVAL);
3673 case 'a' : audio_codec_name = arg; break;
3674 case 's' : subtitle_codec_name = arg; break;
3675 case 'v' : video_codec_name = arg; break;
3677 av_log(NULL, AV_LOG_ERROR,
3678 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3679 return AVERROR(EINVAL);
3686 static const OptionDef options[] = {
3687 #include "cmdutils_common_opts.h"
3688 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3689 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3690 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3691 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3692 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3693 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3694 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3695 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3696 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3697 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3698 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3699 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3700 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3701 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3702 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3703 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3704 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3705 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3706 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3707 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3708 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3709 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3710 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3711 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3712 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3713 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3714 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3715 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3716 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3718 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3719 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3721 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3722 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3723 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3724 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3725 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3726 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3727 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3728 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3729 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3733 static void show_usage(void)
3735 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3736 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3737 av_log(NULL, AV_LOG_INFO, "\n");
3740 void show_help_default(const char *opt, const char *arg)
3742 av_log_set_callback(log_callback_help);
3744 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3745 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3747 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3748 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3749 #if !CONFIG_AVFILTER
3750 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3752 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3754 printf("\nWhile playing:\n"
3756 "f toggle full screen\n"
3758 "a cycle audio channel in the current program\n"
3759 "v cycle video channel\n"
3760 "t cycle subtitle channel in the current program\n"
3762 "w cycle video filters or show modes\n"
3763 "s activate frame-step mode\n"
3764 "left/right seek backward/forward 10 seconds\n"
3765 "down/up seek backward/forward 1 minute\n"
3766 "page down/page up seek backward/forward 10 minutes\n"
3767 "mouse click seek to percentage in file corresponding to fraction of width\n"
3771 static int lockmgr(void **mtx, enum AVLockOp op)
3774 case AV_LOCK_CREATE:
3775 *mtx = SDL_CreateMutex();
3779 case AV_LOCK_OBTAIN:
3780 return !!SDL_LockMutex(*mtx);
3781 case AV_LOCK_RELEASE:
3782 return !!SDL_UnlockMutex(*mtx);
3783 case AV_LOCK_DESTROY:
3784 SDL_DestroyMutex(*mtx);
3790 /* Called from the main */
3791 int main(int argc, char **argv)
3795 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3797 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3798 parse_loglevel(argc, argv, options);
3800 /* register all codecs, demux and protocols */
3802 avdevice_register_all();
3805 avfilter_register_all();
3808 avformat_network_init();
3812 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3813 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3815 show_banner(argc, argv, options);
3817 parse_options(NULL, argc, argv, options, opt_input_file);
3819 if (!input_filename) {
3821 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3822 av_log(NULL, AV_LOG_FATAL,
3823 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3827 if (display_disable) {
3830 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3832 flags &= ~SDL_INIT_AUDIO;
3833 if (display_disable)
3834 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3835 #if !defined(_WIN32) && !defined(__APPLE__)
3836 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3838 if (SDL_Init (flags)) {
3839 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3840 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3844 if (!display_disable) {
3845 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3846 fs_screen_width = vi->current_w;
3847 fs_screen_height = vi->current_h;
3850 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3851 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3852 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3854 if (av_lockmgr_register(lockmgr)) {
3855 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3859 av_init_packet(&flush_pkt);
3860 flush_pkt.data = (uint8_t *)&flush_pkt;
3862 is = stream_open(input_filename, file_iformat);
3864 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");