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_dlog(NULL, "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;
2237 return AVERROR(ENOMEM);
2240 ret = get_video_frame(is, frame);
2247 if ( last_w != frame->width
2248 || last_h != frame->height
2249 || last_format != frame->format
2250 || last_serial != is->viddec.pkt_serial
2251 || last_vfilter_idx != is->vfilter_idx) {
2252 av_log(NULL, AV_LOG_DEBUG,
2253 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2255 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2256 frame->width, frame->height,
2257 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2258 avfilter_graph_free(&graph);
2259 graph = avfilter_graph_alloc();
2260 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2262 event.type = FF_QUIT_EVENT;
2263 event.user.data1 = is;
2264 SDL_PushEvent(&event);
2267 filt_in = is->in_video_filter;
2268 filt_out = is->out_video_filter;
2269 last_w = frame->width;
2270 last_h = frame->height;
2271 last_format = frame->format;
2272 last_serial = is->viddec.pkt_serial;
2273 last_vfilter_idx = is->vfilter_idx;
2274 frame_rate = filt_out->inputs[0]->frame_rate;
2277 ret = av_buffersrc_add_frame(filt_in, frame);
2282 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2284 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2286 if (ret == AVERROR_EOF)
2287 is->viddec.finished = is->viddec.pkt_serial;
2292 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2293 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2294 is->frame_last_filter_delay = 0;
2295 tb = filt_out->inputs[0]->time_base;
2297 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2298 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2299 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2300 av_frame_unref(frame);
2310 avfilter_graph_free(&graph);
2312 av_frame_free(&frame);
2316 static int subtitle_thread(void *arg)
2318 VideoState *is = arg;
2323 int r, g, b, y, u, v, a;
2326 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2329 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2334 if (got_subtitle && sp->sub.format == 0) {
2335 if (sp->sub.pts != AV_NOPTS_VALUE)
2336 pts = sp->sub.pts / (double)AV_TIME_BASE;
2338 sp->serial = is->subdec.pkt_serial;
2340 for (i = 0; i < sp->sub.num_rects; i++)
2342 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2344 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2345 y = RGB_TO_Y_CCIR(r, g, b);
2346 u = RGB_TO_U_CCIR(r, g, b, 0);
2347 v = RGB_TO_V_CCIR(r, g, b, 0);
2348 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2352 /* now we can update the picture count */
2353 frame_queue_push(&is->subpq);
2354 } else if (got_subtitle) {
2355 avsubtitle_free(&sp->sub);
2361 /* copy samples for viewing in editor window */
2362 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2366 size = samples_size / sizeof(short);
2368 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2371 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2373 is->sample_array_index += len;
2374 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2375 is->sample_array_index = 0;
2380 /* return the wanted number of samples to get better sync if sync_type is video
2381 * or external master clock */
2382 static int synchronize_audio(VideoState *is, int nb_samples)
2384 int wanted_nb_samples = nb_samples;
2386 /* if not master, then we try to remove or add samples to correct the clock */
2387 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2388 double diff, avg_diff;
2389 int min_nb_samples, max_nb_samples;
2391 diff = get_clock(&is->audclk) - get_master_clock(is);
2393 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2394 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2395 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2396 /* not enough measures to have a correct estimate */
2397 is->audio_diff_avg_count++;
2399 /* estimate the A-V difference */
2400 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2402 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2403 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2404 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2405 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2406 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2408 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2409 diff, avg_diff, wanted_nb_samples - nb_samples,
2410 is->audio_clock, is->audio_diff_threshold);
2413 /* too big difference : may be initial PTS errors, so
2415 is->audio_diff_avg_count = 0;
2416 is->audio_diff_cum = 0;
2420 return wanted_nb_samples;
2424 * Decode one audio frame and return its uncompressed size.
2426 * The processed audio frame is decoded, converted if required, and
2427 * stored in is->audio_buf, with size in bytes given by the return
2430 static int audio_decode_frame(VideoState *is)
2432 int data_size, resampled_data_size;
2433 int64_t dec_channel_layout;
2434 av_unused double audio_clock0;
2435 int wanted_nb_samples;
2442 if (!(af = frame_queue_peek_readable(&is->sampq)))
2444 frame_queue_next(&is->sampq);
2445 } while (af->serial != is->audioq.serial);
2447 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2448 af->frame->nb_samples,
2449 af->frame->format, 1);
2451 dec_channel_layout =
2452 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2453 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2454 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2456 if (af->frame->format != is->audio_src.fmt ||
2457 dec_channel_layout != is->audio_src.channel_layout ||
2458 af->frame->sample_rate != is->audio_src.freq ||
2459 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2460 swr_free(&is->swr_ctx);
2461 is->swr_ctx = swr_alloc_set_opts(NULL,
2462 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2463 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2465 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2466 av_log(NULL, AV_LOG_ERROR,
2467 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2468 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2469 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2470 swr_free(&is->swr_ctx);
2473 is->audio_src.channel_layout = dec_channel_layout;
2474 is->audio_src.channels = av_frame_get_channels(af->frame);
2475 is->audio_src.freq = af->frame->sample_rate;
2476 is->audio_src.fmt = af->frame->format;
2480 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2481 uint8_t **out = &is->audio_buf1;
2482 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2483 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2486 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2489 if (wanted_nb_samples != af->frame->nb_samples) {
2490 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2491 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2492 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2496 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2497 if (!is->audio_buf1)
2498 return AVERROR(ENOMEM);
2499 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2501 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2504 if (len2 == out_count) {
2505 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2506 if (swr_init(is->swr_ctx) < 0)
2507 swr_free(&is->swr_ctx);
2509 is->audio_buf = is->audio_buf1;
2510 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2512 is->audio_buf = af->frame->data[0];
2513 resampled_data_size = data_size;
2516 audio_clock0 = is->audio_clock;
2517 /* update the audio clock with the pts */
2518 if (!isnan(af->pts))
2519 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2521 is->audio_clock = NAN;
2522 is->audio_clock_serial = af->serial;
2525 static double last_clock;
2526 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2527 is->audio_clock - last_clock,
2528 is->audio_clock, audio_clock0);
2529 last_clock = is->audio_clock;
2532 return resampled_data_size;
2535 /* prepare a new audio buffer */
2536 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2538 VideoState *is = opaque;
2539 int audio_size, len1;
2541 audio_callback_time = av_gettime_relative();
2544 if (is->audio_buf_index >= is->audio_buf_size) {
2545 audio_size = audio_decode_frame(is);
2546 if (audio_size < 0) {
2547 /* if error, just output silence */
2548 is->audio_buf = is->silence_buf;
2549 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2551 if (is->show_mode != SHOW_MODE_VIDEO)
2552 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2553 is->audio_buf_size = audio_size;
2555 is->audio_buf_index = 0;
2557 len1 = is->audio_buf_size - is->audio_buf_index;
2560 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2563 is->audio_buf_index += len1;
2565 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2566 /* Let's assume the audio driver that is used by SDL has two periods. */
2567 if (!isnan(is->audio_clock)) {
2568 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);
2569 sync_clock_to_slave(&is->extclk, &is->audclk);
2573 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2575 SDL_AudioSpec wanted_spec, spec;
2577 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2578 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2579 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2581 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2583 wanted_nb_channels = atoi(env);
2584 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2586 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2587 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2588 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2590 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2591 wanted_spec.channels = wanted_nb_channels;
2592 wanted_spec.freq = wanted_sample_rate;
2593 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2594 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2597 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2598 next_sample_rate_idx--;
2599 wanted_spec.format = AUDIO_S16SYS;
2600 wanted_spec.silence = 0;
2601 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2602 wanted_spec.callback = sdl_audio_callback;
2603 wanted_spec.userdata = opaque;
2604 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2605 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2606 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2607 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2608 if (!wanted_spec.channels) {
2609 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2610 wanted_spec.channels = wanted_nb_channels;
2611 if (!wanted_spec.freq) {
2612 av_log(NULL, AV_LOG_ERROR,
2613 "No more combinations to try, audio open failed\n");
2617 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2619 if (spec.format != AUDIO_S16SYS) {
2620 av_log(NULL, AV_LOG_ERROR,
2621 "SDL advised audio format %d is not supported!\n", spec.format);
2624 if (spec.channels != wanted_spec.channels) {
2625 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2626 if (!wanted_channel_layout) {
2627 av_log(NULL, AV_LOG_ERROR,
2628 "SDL advised channel count %d is not supported!\n", spec.channels);
2633 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2634 audio_hw_params->freq = spec.freq;
2635 audio_hw_params->channel_layout = wanted_channel_layout;
2636 audio_hw_params->channels = spec.channels;
2637 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2638 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);
2639 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2640 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2646 /* open a given stream. Return 0 if OK */
2647 static int stream_component_open(VideoState *is, int stream_index)
2649 AVFormatContext *ic = is->ic;
2650 AVCodecContext *avctx;
2652 const char *forced_codec_name = NULL;
2654 AVDictionaryEntry *t = NULL;
2655 int sample_rate, nb_channels;
2656 int64_t channel_layout;
2658 int stream_lowres = lowres;
2660 if (stream_index < 0 || stream_index >= ic->nb_streams)
2662 avctx = ic->streams[stream_index]->codec;
2664 codec = avcodec_find_decoder(avctx->codec_id);
2666 switch(avctx->codec_type){
2667 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2668 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2669 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2671 if (forced_codec_name)
2672 codec = avcodec_find_decoder_by_name(forced_codec_name);
2674 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2675 "No codec could be found with name '%s'\n", forced_codec_name);
2676 else av_log(NULL, AV_LOG_WARNING,
2677 "No codec could be found with id %d\n", avctx->codec_id);
2681 avctx->codec_id = codec->id;
2682 if(stream_lowres > av_codec_get_max_lowres(codec)){
2683 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2684 av_codec_get_max_lowres(codec));
2685 stream_lowres = av_codec_get_max_lowres(codec);
2687 av_codec_set_lowres(avctx, stream_lowres);
2689 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2690 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2691 if(codec->capabilities & CODEC_CAP_DR1)
2692 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2694 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2695 if (!av_dict_get(opts, "threads", NULL, 0))
2696 av_dict_set(&opts, "threads", "auto", 0);
2698 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2699 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2700 av_dict_set(&opts, "refcounted_frames", "1", 0);
2701 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2704 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2705 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2706 ret = AVERROR_OPTION_NOT_FOUND;
2711 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2712 switch (avctx->codec_type) {
2713 case AVMEDIA_TYPE_AUDIO:
2718 is->audio_filter_src.freq = avctx->sample_rate;
2719 is->audio_filter_src.channels = avctx->channels;
2720 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2721 is->audio_filter_src.fmt = avctx->sample_fmt;
2722 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2724 link = is->out_audio_filter->inputs[0];
2725 sample_rate = link->sample_rate;
2726 nb_channels = link->channels;
2727 channel_layout = link->channel_layout;
2730 sample_rate = avctx->sample_rate;
2731 nb_channels = avctx->channels;
2732 channel_layout = avctx->channel_layout;
2735 /* prepare audio output */
2736 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2738 is->audio_hw_buf_size = ret;
2739 is->audio_src = is->audio_tgt;
2740 is->audio_buf_size = 0;
2741 is->audio_buf_index = 0;
2743 /* init averaging filter */
2744 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2745 is->audio_diff_avg_count = 0;
2746 /* since we do not have a precise anough audio fifo fullness,
2747 we correct audio sync only if larger than this threshold */
2748 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2750 is->audio_stream = stream_index;
2751 is->audio_st = ic->streams[stream_index];
2753 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2754 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2755 is->auddec.start_pts = is->audio_st->start_time;
2756 is->auddec.start_pts_tb = is->audio_st->time_base;
2758 decoder_start(&is->auddec, audio_thread, is);
2761 case AVMEDIA_TYPE_VIDEO:
2762 is->video_stream = stream_index;
2763 is->video_st = ic->streams[stream_index];
2765 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2766 decoder_start(&is->viddec, video_thread, is);
2767 is->queue_attachments_req = 1;
2769 case AVMEDIA_TYPE_SUBTITLE:
2770 is->subtitle_stream = stream_index;
2771 is->subtitle_st = ic->streams[stream_index];
2773 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2774 decoder_start(&is->subdec, subtitle_thread, is);
2781 av_dict_free(&opts);
2786 static void stream_component_close(VideoState *is, int stream_index)
2788 AVFormatContext *ic = is->ic;
2789 AVCodecContext *avctx;
2791 if (stream_index < 0 || stream_index >= ic->nb_streams)
2793 avctx = ic->streams[stream_index]->codec;
2795 switch (avctx->codec_type) {
2796 case AVMEDIA_TYPE_AUDIO:
2797 decoder_abort(&is->auddec, &is->sampq);
2799 decoder_destroy(&is->auddec);
2800 swr_free(&is->swr_ctx);
2801 av_freep(&is->audio_buf1);
2802 is->audio_buf1_size = 0;
2803 is->audio_buf = NULL;
2806 av_rdft_end(is->rdft);
2807 av_freep(&is->rdft_data);
2812 case AVMEDIA_TYPE_VIDEO:
2813 decoder_abort(&is->viddec, &is->pictq);
2814 decoder_destroy(&is->viddec);
2816 case AVMEDIA_TYPE_SUBTITLE:
2817 decoder_abort(&is->subdec, &is->subpq);
2818 decoder_destroy(&is->subdec);
2824 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2825 avcodec_close(avctx);
2826 switch (avctx->codec_type) {
2827 case AVMEDIA_TYPE_AUDIO:
2828 is->audio_st = NULL;
2829 is->audio_stream = -1;
2831 case AVMEDIA_TYPE_VIDEO:
2832 is->video_st = NULL;
2833 is->video_stream = -1;
2835 case AVMEDIA_TYPE_SUBTITLE:
2836 is->subtitle_st = NULL;
2837 is->subtitle_stream = -1;
2844 static int decode_interrupt_cb(void *ctx)
2846 VideoState *is = ctx;
2847 return is->abort_request;
2850 static int is_realtime(AVFormatContext *s)
2852 if( !strcmp(s->iformat->name, "rtp")
2853 || !strcmp(s->iformat->name, "rtsp")
2854 || !strcmp(s->iformat->name, "sdp")
2858 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2859 || !strncmp(s->filename, "udp:", 4)
2866 /* this thread gets the stream from the disk or the network */
2867 static int read_thread(void *arg)
2869 VideoState *is = arg;
2870 AVFormatContext *ic = NULL;
2872 int st_index[AVMEDIA_TYPE_NB];
2873 AVPacket pkt1, *pkt = &pkt1;
2874 int64_t stream_start_time;
2875 int pkt_in_play_range = 0;
2876 AVDictionaryEntry *t;
2877 AVDictionary **opts;
2878 int orig_nb_streams;
2879 SDL_mutex *wait_mutex = SDL_CreateMutex();
2880 int scan_all_pmts_set = 0;
2883 memset(st_index, -1, sizeof(st_index));
2884 is->last_video_stream = is->video_stream = -1;
2885 is->last_audio_stream = is->audio_stream = -1;
2886 is->last_subtitle_stream = is->subtitle_stream = -1;
2889 ic = avformat_alloc_context();
2891 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2892 ret = AVERROR(ENOMEM);
2895 ic->interrupt_callback.callback = decode_interrupt_cb;
2896 ic->interrupt_callback.opaque = is;
2897 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2898 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2899 scan_all_pmts_set = 1;
2901 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2903 print_error(is->filename, err);
2907 if (scan_all_pmts_set)
2908 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2910 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2911 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2912 ret = AVERROR_OPTION_NOT_FOUND;
2918 ic->flags |= AVFMT_FLAG_GENPTS;
2920 av_format_inject_global_side_data(ic);
2922 opts = setup_find_stream_info_opts(ic, codec_opts);
2923 orig_nb_streams = ic->nb_streams;
2925 err = avformat_find_stream_info(ic, opts);
2927 for (i = 0; i < orig_nb_streams; i++)
2928 av_dict_free(&opts[i]);
2932 av_log(NULL, AV_LOG_WARNING,
2933 "%s: could not find codec parameters\n", is->filename);
2939 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2941 if (seek_by_bytes < 0)
2942 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2944 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2946 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2947 window_title = av_asprintf("%s - %s", t->value, input_filename);
2949 /* if seeking requested, we execute it */
2950 if (start_time != AV_NOPTS_VALUE) {
2953 timestamp = start_time;
2954 /* add the stream start time */
2955 if (ic->start_time != AV_NOPTS_VALUE)
2956 timestamp += ic->start_time;
2957 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2959 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2960 is->filename, (double)timestamp / AV_TIME_BASE);
2964 is->realtime = is_realtime(ic);
2967 av_dump_format(ic, 0, is->filename, 0);
2969 for (i = 0; i < ic->nb_streams; i++) {
2970 AVStream *st = ic->streams[i];
2971 enum AVMediaType type = st->codec->codec_type;
2972 st->discard = AVDISCARD_ALL;
2973 if (wanted_stream_spec[type] && st_index[type] == -1)
2974 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2977 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2978 if (wanted_stream_spec[i] && st_index[i] == -1) {
2979 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));
2980 st_index[i] = INT_MAX;
2985 st_index[AVMEDIA_TYPE_VIDEO] =
2986 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2987 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2989 st_index[AVMEDIA_TYPE_AUDIO] =
2990 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2991 st_index[AVMEDIA_TYPE_AUDIO],
2992 st_index[AVMEDIA_TYPE_VIDEO],
2994 if (!video_disable && !subtitle_disable)
2995 st_index[AVMEDIA_TYPE_SUBTITLE] =
2996 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2997 st_index[AVMEDIA_TYPE_SUBTITLE],
2998 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2999 st_index[AVMEDIA_TYPE_AUDIO] :
3000 st_index[AVMEDIA_TYPE_VIDEO]),
3003 is->show_mode = show_mode;
3004 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3005 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
3006 AVCodecContext *avctx = st->codec;
3007 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
3009 set_default_window_size(avctx->width, avctx->height, sar);
3012 /* open the streams */
3013 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
3014 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
3018 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3019 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
3021 if (is->show_mode == SHOW_MODE_NONE)
3022 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
3024 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
3025 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
3028 if (is->video_stream < 0 && is->audio_stream < 0) {
3029 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
3035 if (infinite_buffer < 0 && is->realtime)
3036 infinite_buffer = 1;
3039 if (is->abort_request)
3041 if (is->paused != is->last_paused) {
3042 is->last_paused = is->paused;
3044 is->read_pause_return = av_read_pause(ic);
3048 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3050 (!strcmp(ic->iformat->name, "rtsp") ||
3051 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3052 /* wait 10 ms to avoid trying to get another packet */
3059 int64_t seek_target = is->seek_pos;
3060 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3061 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3062 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3063 // of the seek_pos/seek_rel variables
3065 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3067 av_log(NULL, AV_LOG_ERROR,
3068 "%s: error while seeking\n", is->ic->filename);
3070 if (is->audio_stream >= 0) {
3071 packet_queue_flush(&is->audioq);
3072 packet_queue_put(&is->audioq, &flush_pkt);
3074 if (is->subtitle_stream >= 0) {
3075 packet_queue_flush(&is->subtitleq);
3076 packet_queue_put(&is->subtitleq, &flush_pkt);
3078 if (is->video_stream >= 0) {
3079 packet_queue_flush(&is->videoq);
3080 packet_queue_put(&is->videoq, &flush_pkt);
3082 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3083 set_clock(&is->extclk, NAN, 0);
3085 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3089 is->queue_attachments_req = 1;
3092 step_to_next_frame(is);
3094 if (is->queue_attachments_req) {
3095 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3097 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3099 packet_queue_put(&is->videoq, ©);
3100 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3102 is->queue_attachments_req = 0;
3105 /* if the queue are full, no need to read more */
3106 if (infinite_buffer<1 &&
3107 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3108 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3109 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3110 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3111 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3113 SDL_LockMutex(wait_mutex);
3114 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3115 SDL_UnlockMutex(wait_mutex);
3119 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3120 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3121 if (loop != 1 && (!loop || --loop)) {
3122 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3123 } else if (autoexit) {
3128 ret = av_read_frame(ic, pkt);
3130 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3131 if (is->video_stream >= 0)
3132 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3133 if (is->audio_stream >= 0)
3134 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3135 if (is->subtitle_stream >= 0)
3136 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3139 if (ic->pb && ic->pb->error)
3141 SDL_LockMutex(wait_mutex);
3142 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3143 SDL_UnlockMutex(wait_mutex);
3148 /* check if packet is in play range specified by user, then queue, otherwise discard */
3149 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3150 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3151 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3152 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3153 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3154 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3155 <= ((double)duration / 1000000);
3156 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3157 packet_queue_put(&is->audioq, pkt);
3158 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3159 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3160 packet_queue_put(&is->videoq, pkt);
3161 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3162 packet_queue_put(&is->subtitleq, pkt);
3164 av_free_packet(pkt);
3167 /* wait until the end */
3168 while (!is->abort_request) {
3174 /* close each stream */
3175 if (is->audio_stream >= 0)
3176 stream_component_close(is, is->audio_stream);
3177 if (is->video_stream >= 0)
3178 stream_component_close(is, is->video_stream);
3179 if (is->subtitle_stream >= 0)
3180 stream_component_close(is, is->subtitle_stream);
3182 avformat_close_input(&ic);
3189 event.type = FF_QUIT_EVENT;
3190 event.user.data1 = is;
3191 SDL_PushEvent(&event);
3193 SDL_DestroyMutex(wait_mutex);
3197 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3201 is = av_mallocz(sizeof(VideoState));
3204 av_strlcpy(is->filename, filename, sizeof(is->filename));
3205 is->iformat = iformat;
3209 /* start video display */
3210 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3212 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3214 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3217 packet_queue_init(&is->videoq);
3218 packet_queue_init(&is->audioq);
3219 packet_queue_init(&is->subtitleq);
3221 is->continue_read_thread = SDL_CreateCond();
3223 init_clock(&is->vidclk, &is->videoq.serial);
3224 init_clock(&is->audclk, &is->audioq.serial);
3225 init_clock(&is->extclk, &is->extclk.serial);
3226 is->audio_clock_serial = -1;
3227 is->av_sync_type = av_sync_type;
3228 is->read_tid = SDL_CreateThread(read_thread, is);
3229 if (!is->read_tid) {
3237 static void stream_cycle_channel(VideoState *is, int codec_type)
3239 AVFormatContext *ic = is->ic;
3240 int start_index, stream_index;
3243 AVProgram *p = NULL;
3244 int nb_streams = is->ic->nb_streams;
3246 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3247 start_index = is->last_video_stream;
3248 old_index = is->video_stream;
3249 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3250 start_index = is->last_audio_stream;
3251 old_index = is->audio_stream;
3253 start_index = is->last_subtitle_stream;
3254 old_index = is->subtitle_stream;
3256 stream_index = start_index;
3258 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3259 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3261 nb_streams = p->nb_stream_indexes;
3262 for (start_index = 0; start_index < nb_streams; start_index++)
3263 if (p->stream_index[start_index] == stream_index)
3265 if (start_index == nb_streams)
3267 stream_index = start_index;
3272 if (++stream_index >= nb_streams)
3274 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3277 is->last_subtitle_stream = -1;
3280 if (start_index == -1)
3284 if (stream_index == start_index)
3286 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3287 if (st->codec->codec_type == codec_type) {
3288 /* check that parameters are OK */
3289 switch (codec_type) {
3290 case AVMEDIA_TYPE_AUDIO:
3291 if (st->codec->sample_rate != 0 &&
3292 st->codec->channels != 0)
3295 case AVMEDIA_TYPE_VIDEO:
3296 case AVMEDIA_TYPE_SUBTITLE:
3304 if (p && stream_index != -1)
3305 stream_index = p->stream_index[stream_index];
3306 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3307 av_get_media_type_string(codec_type),
3311 stream_component_close(is, old_index);
3312 stream_component_open(is, stream_index);
3316 static void toggle_full_screen(VideoState *is)
3318 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3319 /* OS X needs to reallocate the SDL overlays */
3321 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3322 is->pictq.queue[i].reallocate = 1;
3324 is_full_screen = !is_full_screen;
3325 video_open(is, 1, NULL);
3328 static void toggle_audio_display(VideoState *is)
3330 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3331 int next = is->show_mode;
3333 next = (next + 1) % SHOW_MODE_NB;
3334 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3335 if (is->show_mode != next) {
3336 fill_rectangle(screen,
3337 is->xleft, is->ytop, is->width, is->height,
3339 is->force_refresh = 1;
3340 is->show_mode = next;
3344 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3345 double remaining_time = 0.0;
3347 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3348 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3352 if (remaining_time > 0.0)
3353 av_usleep((int64_t)(remaining_time * 1000000.0));
3354 remaining_time = REFRESH_RATE;
3355 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3356 video_refresh(is, &remaining_time);
3361 static void seek_chapter(VideoState *is, int incr)
3363 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3366 if (!is->ic->nb_chapters)
3369 /* find the current chapter */
3370 for (i = 0; i < is->ic->nb_chapters; i++) {
3371 AVChapter *ch = is->ic->chapters[i];
3372 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3380 if (i >= is->ic->nb_chapters)
3383 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3384 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3385 AV_TIME_BASE_Q), 0, 0);
3388 /* handle an event sent by the GUI */
3389 static void event_loop(VideoState *cur_stream)
3392 double incr, pos, frac;
3396 refresh_loop_wait_event(cur_stream, &event);
3397 switch (event.type) {
3399 if (exit_on_keydown) {
3400 do_exit(cur_stream);
3403 switch (event.key.keysym.sym) {
3406 do_exit(cur_stream);
3409 toggle_full_screen(cur_stream);
3410 cur_stream->force_refresh = 1;
3414 toggle_pause(cur_stream);
3416 case SDLK_s: // S: Step to next frame
3417 step_to_next_frame(cur_stream);
3420 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3423 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3426 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3427 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3428 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3431 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3435 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3436 if (++cur_stream->vfilter_idx >= nb_vfilters)
3437 cur_stream->vfilter_idx = 0;
3439 cur_stream->vfilter_idx = 0;
3440 toggle_audio_display(cur_stream);
3443 toggle_audio_display(cur_stream);
3447 if (cur_stream->ic->nb_chapters <= 1) {
3451 seek_chapter(cur_stream, 1);
3454 if (cur_stream->ic->nb_chapters <= 1) {
3458 seek_chapter(cur_stream, -1);
3472 if (seek_by_bytes) {
3474 if (pos < 0 && cur_stream->video_stream >= 0)
3475 pos = frame_queue_last_pos(&cur_stream->pictq);
3476 if (pos < 0 && cur_stream->audio_stream >= 0)
3477 pos = frame_queue_last_pos(&cur_stream->sampq);
3479 pos = avio_tell(cur_stream->ic->pb);
3480 if (cur_stream->ic->bit_rate)
3481 incr *= cur_stream->ic->bit_rate / 8.0;
3485 stream_seek(cur_stream, pos, incr, 1);
3487 pos = get_master_clock(cur_stream);
3489 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3491 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3492 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3493 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3500 case SDL_VIDEOEXPOSE:
3501 cur_stream->force_refresh = 1;
3503 case SDL_MOUSEBUTTONDOWN:
3504 if (exit_on_mousedown) {
3505 do_exit(cur_stream);
3508 case SDL_MOUSEMOTION:
3509 if (cursor_hidden) {
3513 cursor_last_shown = av_gettime_relative();
3514 if (event.type == SDL_MOUSEBUTTONDOWN) {
3517 if (event.motion.state != SDL_PRESSED)
3521 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3522 uint64_t size = avio_size(cur_stream->ic->pb);
3523 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3527 int tns, thh, tmm, tss;
3528 tns = cur_stream->ic->duration / 1000000LL;
3530 tmm = (tns % 3600) / 60;
3532 frac = x / cur_stream->width;
3535 mm = (ns % 3600) / 60;
3537 av_log(NULL, AV_LOG_INFO,
3538 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3539 hh, mm, ss, thh, tmm, tss);
3540 ts = frac * cur_stream->ic->duration;
3541 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3542 ts += cur_stream->ic->start_time;
3543 stream_seek(cur_stream, ts, 0, 0);
3546 case SDL_VIDEORESIZE:
3547 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3548 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3550 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3551 do_exit(cur_stream);
3553 screen_width = cur_stream->width = screen->w;
3554 screen_height = cur_stream->height = screen->h;
3555 cur_stream->force_refresh = 1;
3559 do_exit(cur_stream);
3561 case FF_ALLOC_EVENT:
3562 alloc_picture(event.user.data1);
3570 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3572 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3573 return opt_default(NULL, "video_size", arg);
3576 static int opt_width(void *optctx, const char *opt, const char *arg)
3578 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3582 static int opt_height(void *optctx, const char *opt, const char *arg)
3584 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3588 static int opt_format(void *optctx, const char *opt, const char *arg)
3590 file_iformat = av_find_input_format(arg);
3591 if (!file_iformat) {
3592 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3593 return AVERROR(EINVAL);
3598 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3600 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3601 return opt_default(NULL, "pixel_format", arg);
3604 static int opt_sync(void *optctx, const char *opt, const char *arg)
3606 if (!strcmp(arg, "audio"))
3607 av_sync_type = AV_SYNC_AUDIO_MASTER;
3608 else if (!strcmp(arg, "video"))
3609 av_sync_type = AV_SYNC_VIDEO_MASTER;
3610 else if (!strcmp(arg, "ext"))
3611 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3613 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3619 static int opt_seek(void *optctx, const char *opt, const char *arg)
3621 start_time = parse_time_or_die(opt, arg, 1);
3625 static int opt_duration(void *optctx, const char *opt, const char *arg)
3627 duration = parse_time_or_die(opt, arg, 1);
3631 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3633 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3634 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3635 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3636 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3640 static void opt_input_file(void *optctx, const char *filename)
3642 if (input_filename) {
3643 av_log(NULL, AV_LOG_FATAL,
3644 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3645 filename, input_filename);
3648 if (!strcmp(filename, "-"))
3650 input_filename = filename;
3653 static int opt_codec(void *optctx, const char *opt, const char *arg)
3655 const char *spec = strchr(opt, ':');
3657 av_log(NULL, AV_LOG_ERROR,
3658 "No media specifier was specified in '%s' in option '%s'\n",
3660 return AVERROR(EINVAL);
3664 case 'a' : audio_codec_name = arg; break;
3665 case 's' : subtitle_codec_name = arg; break;
3666 case 'v' : video_codec_name = arg; break;
3668 av_log(NULL, AV_LOG_ERROR,
3669 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3670 return AVERROR(EINVAL);
3677 static const OptionDef options[] = {
3678 #include "cmdutils_common_opts.h"
3679 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3680 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3681 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3682 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3683 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3684 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3685 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3686 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3687 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3688 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3689 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3690 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3691 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3692 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3693 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3694 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3695 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3696 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3697 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3698 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3699 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3700 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3701 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3702 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3703 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3704 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3705 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3706 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3707 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3709 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3710 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3712 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3713 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3714 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3715 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3716 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3717 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3718 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3719 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3720 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3724 static void show_usage(void)
3726 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3727 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3728 av_log(NULL, AV_LOG_INFO, "\n");
3731 void show_help_default(const char *opt, const char *arg)
3733 av_log_set_callback(log_callback_help);
3735 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3736 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3738 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3739 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3740 #if !CONFIG_AVFILTER
3741 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3743 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3745 printf("\nWhile playing:\n"
3747 "f toggle full screen\n"
3749 "a cycle audio channel in the current program\n"
3750 "v cycle video channel\n"
3751 "t cycle subtitle channel in the current program\n"
3753 "w cycle video filters or show modes\n"
3754 "s activate frame-step mode\n"
3755 "left/right seek backward/forward 10 seconds\n"
3756 "down/up seek backward/forward 1 minute\n"
3757 "page down/page up seek backward/forward 10 minutes\n"
3758 "mouse click seek to percentage in file corresponding to fraction of width\n"
3762 static int lockmgr(void **mtx, enum AVLockOp op)
3765 case AV_LOCK_CREATE:
3766 *mtx = SDL_CreateMutex();
3770 case AV_LOCK_OBTAIN:
3771 return !!SDL_LockMutex(*mtx);
3772 case AV_LOCK_RELEASE:
3773 return !!SDL_UnlockMutex(*mtx);
3774 case AV_LOCK_DESTROY:
3775 SDL_DestroyMutex(*mtx);
3781 /* Called from the main */
3782 int main(int argc, char **argv)
3786 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3788 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3789 parse_loglevel(argc, argv, options);
3791 /* register all codecs, demux and protocols */
3793 avdevice_register_all();
3796 avfilter_register_all();
3799 avformat_network_init();
3803 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3804 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3806 show_banner(argc, argv, options);
3808 parse_options(NULL, argc, argv, options, opt_input_file);
3810 if (!input_filename) {
3812 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3813 av_log(NULL, AV_LOG_FATAL,
3814 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3818 if (display_disable) {
3821 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3823 flags &= ~SDL_INIT_AUDIO;
3824 if (display_disable)
3825 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3826 #if !defined(_WIN32) && !defined(__APPLE__)
3827 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3829 if (SDL_Init (flags)) {
3830 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3831 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3835 if (!display_disable) {
3836 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3837 fs_screen_width = vi->current_w;
3838 fs_screen_height = vi->current_h;
3841 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3842 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3843 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3845 if (av_lockmgr_register(lockmgr)) {
3846 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3850 av_init_packet(&flush_pkt);
3851 flush_pkt.data = (uint8_t *)&flush_pkt;
3853 is = stream_open(input_filename, file_iformat);
3855 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");