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;
2235 return AVERROR(ENOMEM);
2240 return AVERROR(ENOMEM);
2243 ret = get_video_frame(is, frame);
2250 if ( last_w != frame->width
2251 || last_h != frame->height
2252 || last_format != frame->format
2253 || last_serial != is->viddec.pkt_serial
2254 || last_vfilter_idx != is->vfilter_idx) {
2255 av_log(NULL, AV_LOG_DEBUG,
2256 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2258 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2259 frame->width, frame->height,
2260 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2261 avfilter_graph_free(&graph);
2262 graph = avfilter_graph_alloc();
2263 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2265 event.type = FF_QUIT_EVENT;
2266 event.user.data1 = is;
2267 SDL_PushEvent(&event);
2270 filt_in = is->in_video_filter;
2271 filt_out = is->out_video_filter;
2272 last_w = frame->width;
2273 last_h = frame->height;
2274 last_format = frame->format;
2275 last_serial = is->viddec.pkt_serial;
2276 last_vfilter_idx = is->vfilter_idx;
2277 frame_rate = filt_out->inputs[0]->frame_rate;
2280 ret = av_buffersrc_add_frame(filt_in, frame);
2285 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2287 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2289 if (ret == AVERROR_EOF)
2290 is->viddec.finished = is->viddec.pkt_serial;
2295 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2296 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2297 is->frame_last_filter_delay = 0;
2298 tb = filt_out->inputs[0]->time_base;
2300 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2301 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2302 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2303 av_frame_unref(frame);
2313 avfilter_graph_free(&graph);
2315 av_frame_free(&frame);
2319 static int subtitle_thread(void *arg)
2321 VideoState *is = arg;
2326 int r, g, b, y, u, v, a;
2329 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2332 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2337 if (got_subtitle && sp->sub.format == 0) {
2338 if (sp->sub.pts != AV_NOPTS_VALUE)
2339 pts = sp->sub.pts / (double)AV_TIME_BASE;
2341 sp->serial = is->subdec.pkt_serial;
2343 for (i = 0; i < sp->sub.num_rects; i++)
2345 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2347 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2348 y = RGB_TO_Y_CCIR(r, g, b);
2349 u = RGB_TO_U_CCIR(r, g, b, 0);
2350 v = RGB_TO_V_CCIR(r, g, b, 0);
2351 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2355 /* now we can update the picture count */
2356 frame_queue_push(&is->subpq);
2357 } else if (got_subtitle) {
2358 avsubtitle_free(&sp->sub);
2364 /* copy samples for viewing in editor window */
2365 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2369 size = samples_size / sizeof(short);
2371 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2374 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2376 is->sample_array_index += len;
2377 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2378 is->sample_array_index = 0;
2383 /* return the wanted number of samples to get better sync if sync_type is video
2384 * or external master clock */
2385 static int synchronize_audio(VideoState *is, int nb_samples)
2387 int wanted_nb_samples = nb_samples;
2389 /* if not master, then we try to remove or add samples to correct the clock */
2390 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2391 double diff, avg_diff;
2392 int min_nb_samples, max_nb_samples;
2394 diff = get_clock(&is->audclk) - get_master_clock(is);
2396 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2397 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2398 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2399 /* not enough measures to have a correct estimate */
2400 is->audio_diff_avg_count++;
2402 /* estimate the A-V difference */
2403 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2405 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2406 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2407 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2408 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2409 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2411 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2412 diff, avg_diff, wanted_nb_samples - nb_samples,
2413 is->audio_clock, is->audio_diff_threshold);
2416 /* too big difference : may be initial PTS errors, so
2418 is->audio_diff_avg_count = 0;
2419 is->audio_diff_cum = 0;
2423 return wanted_nb_samples;
2427 * Decode one audio frame and return its uncompressed size.
2429 * The processed audio frame is decoded, converted if required, and
2430 * stored in is->audio_buf, with size in bytes given by the return
2433 static int audio_decode_frame(VideoState *is)
2435 int data_size, resampled_data_size;
2436 int64_t dec_channel_layout;
2437 av_unused double audio_clock0;
2438 int wanted_nb_samples;
2445 if (!(af = frame_queue_peek_readable(&is->sampq)))
2447 frame_queue_next(&is->sampq);
2448 } while (af->serial != is->audioq.serial);
2450 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2451 af->frame->nb_samples,
2452 af->frame->format, 1);
2454 dec_channel_layout =
2455 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2456 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2457 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2459 if (af->frame->format != is->audio_src.fmt ||
2460 dec_channel_layout != is->audio_src.channel_layout ||
2461 af->frame->sample_rate != is->audio_src.freq ||
2462 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2463 swr_free(&is->swr_ctx);
2464 is->swr_ctx = swr_alloc_set_opts(NULL,
2465 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2466 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2468 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2469 av_log(NULL, AV_LOG_ERROR,
2470 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2471 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2472 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2473 swr_free(&is->swr_ctx);
2476 is->audio_src.channel_layout = dec_channel_layout;
2477 is->audio_src.channels = av_frame_get_channels(af->frame);
2478 is->audio_src.freq = af->frame->sample_rate;
2479 is->audio_src.fmt = af->frame->format;
2483 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2484 uint8_t **out = &is->audio_buf1;
2485 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2486 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2489 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2492 if (wanted_nb_samples != af->frame->nb_samples) {
2493 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2494 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2495 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2499 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2500 if (!is->audio_buf1)
2501 return AVERROR(ENOMEM);
2502 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2504 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2507 if (len2 == out_count) {
2508 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2509 if (swr_init(is->swr_ctx) < 0)
2510 swr_free(&is->swr_ctx);
2512 is->audio_buf = is->audio_buf1;
2513 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2515 is->audio_buf = af->frame->data[0];
2516 resampled_data_size = data_size;
2519 audio_clock0 = is->audio_clock;
2520 /* update the audio clock with the pts */
2521 if (!isnan(af->pts))
2522 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2524 is->audio_clock = NAN;
2525 is->audio_clock_serial = af->serial;
2528 static double last_clock;
2529 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2530 is->audio_clock - last_clock,
2531 is->audio_clock, audio_clock0);
2532 last_clock = is->audio_clock;
2535 return resampled_data_size;
2538 /* prepare a new audio buffer */
2539 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2541 VideoState *is = opaque;
2542 int audio_size, len1;
2544 audio_callback_time = av_gettime_relative();
2547 if (is->audio_buf_index >= is->audio_buf_size) {
2548 audio_size = audio_decode_frame(is);
2549 if (audio_size < 0) {
2550 /* if error, just output silence */
2551 is->audio_buf = is->silence_buf;
2552 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2554 if (is->show_mode != SHOW_MODE_VIDEO)
2555 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2556 is->audio_buf_size = audio_size;
2558 is->audio_buf_index = 0;
2560 len1 = is->audio_buf_size - is->audio_buf_index;
2563 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2566 is->audio_buf_index += len1;
2568 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2569 /* Let's assume the audio driver that is used by SDL has two periods. */
2570 if (!isnan(is->audio_clock)) {
2571 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);
2572 sync_clock_to_slave(&is->extclk, &is->audclk);
2576 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2578 SDL_AudioSpec wanted_spec, spec;
2580 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2581 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2582 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2584 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2586 wanted_nb_channels = atoi(env);
2587 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2589 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2590 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2591 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2593 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2594 wanted_spec.channels = wanted_nb_channels;
2595 wanted_spec.freq = wanted_sample_rate;
2596 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2597 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2600 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2601 next_sample_rate_idx--;
2602 wanted_spec.format = AUDIO_S16SYS;
2603 wanted_spec.silence = 0;
2604 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2605 wanted_spec.callback = sdl_audio_callback;
2606 wanted_spec.userdata = opaque;
2607 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2608 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2609 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2610 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2611 if (!wanted_spec.channels) {
2612 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2613 wanted_spec.channels = wanted_nb_channels;
2614 if (!wanted_spec.freq) {
2615 av_log(NULL, AV_LOG_ERROR,
2616 "No more combinations to try, audio open failed\n");
2620 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2622 if (spec.format != AUDIO_S16SYS) {
2623 av_log(NULL, AV_LOG_ERROR,
2624 "SDL advised audio format %d is not supported!\n", spec.format);
2627 if (spec.channels != wanted_spec.channels) {
2628 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2629 if (!wanted_channel_layout) {
2630 av_log(NULL, AV_LOG_ERROR,
2631 "SDL advised channel count %d is not supported!\n", spec.channels);
2636 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2637 audio_hw_params->freq = spec.freq;
2638 audio_hw_params->channel_layout = wanted_channel_layout;
2639 audio_hw_params->channels = spec.channels;
2640 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2641 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);
2642 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2643 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2649 /* open a given stream. Return 0 if OK */
2650 static int stream_component_open(VideoState *is, int stream_index)
2652 AVFormatContext *ic = is->ic;
2653 AVCodecContext *avctx;
2655 const char *forced_codec_name = NULL;
2657 AVDictionaryEntry *t = NULL;
2658 int sample_rate, nb_channels;
2659 int64_t channel_layout;
2661 int stream_lowres = lowres;
2663 if (stream_index < 0 || stream_index >= ic->nb_streams)
2665 avctx = ic->streams[stream_index]->codec;
2667 codec = avcodec_find_decoder(avctx->codec_id);
2669 switch(avctx->codec_type){
2670 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2671 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2672 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2674 if (forced_codec_name)
2675 codec = avcodec_find_decoder_by_name(forced_codec_name);
2677 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2678 "No codec could be found with name '%s'\n", forced_codec_name);
2679 else av_log(NULL, AV_LOG_WARNING,
2680 "No codec could be found with id %d\n", avctx->codec_id);
2684 avctx->codec_id = codec->id;
2685 if(stream_lowres > av_codec_get_max_lowres(codec)){
2686 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2687 av_codec_get_max_lowres(codec));
2688 stream_lowres = av_codec_get_max_lowres(codec);
2690 av_codec_set_lowres(avctx, stream_lowres);
2692 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2693 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2694 if(codec->capabilities & CODEC_CAP_DR1)
2695 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2697 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2698 if (!av_dict_get(opts, "threads", NULL, 0))
2699 av_dict_set(&opts, "threads", "auto", 0);
2701 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2702 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2703 av_dict_set(&opts, "refcounted_frames", "1", 0);
2704 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2707 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2708 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2709 ret = AVERROR_OPTION_NOT_FOUND;
2714 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2715 switch (avctx->codec_type) {
2716 case AVMEDIA_TYPE_AUDIO:
2721 is->audio_filter_src.freq = avctx->sample_rate;
2722 is->audio_filter_src.channels = avctx->channels;
2723 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2724 is->audio_filter_src.fmt = avctx->sample_fmt;
2725 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2727 link = is->out_audio_filter->inputs[0];
2728 sample_rate = link->sample_rate;
2729 nb_channels = link->channels;
2730 channel_layout = link->channel_layout;
2733 sample_rate = avctx->sample_rate;
2734 nb_channels = avctx->channels;
2735 channel_layout = avctx->channel_layout;
2738 /* prepare audio output */
2739 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2741 is->audio_hw_buf_size = ret;
2742 is->audio_src = is->audio_tgt;
2743 is->audio_buf_size = 0;
2744 is->audio_buf_index = 0;
2746 /* init averaging filter */
2747 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2748 is->audio_diff_avg_count = 0;
2749 /* since we do not have a precise anough audio fifo fullness,
2750 we correct audio sync only if larger than this threshold */
2751 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2753 is->audio_stream = stream_index;
2754 is->audio_st = ic->streams[stream_index];
2756 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2757 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2758 is->auddec.start_pts = is->audio_st->start_time;
2759 is->auddec.start_pts_tb = is->audio_st->time_base;
2761 decoder_start(&is->auddec, audio_thread, is);
2764 case AVMEDIA_TYPE_VIDEO:
2765 is->video_stream = stream_index;
2766 is->video_st = ic->streams[stream_index];
2768 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2769 decoder_start(&is->viddec, video_thread, is);
2770 is->queue_attachments_req = 1;
2772 case AVMEDIA_TYPE_SUBTITLE:
2773 is->subtitle_stream = stream_index;
2774 is->subtitle_st = ic->streams[stream_index];
2776 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2777 decoder_start(&is->subdec, subtitle_thread, is);
2784 av_dict_free(&opts);
2789 static void stream_component_close(VideoState *is, int stream_index)
2791 AVFormatContext *ic = is->ic;
2792 AVCodecContext *avctx;
2794 if (stream_index < 0 || stream_index >= ic->nb_streams)
2796 avctx = ic->streams[stream_index]->codec;
2798 switch (avctx->codec_type) {
2799 case AVMEDIA_TYPE_AUDIO:
2800 decoder_abort(&is->auddec, &is->sampq);
2802 decoder_destroy(&is->auddec);
2803 swr_free(&is->swr_ctx);
2804 av_freep(&is->audio_buf1);
2805 is->audio_buf1_size = 0;
2806 is->audio_buf = NULL;
2809 av_rdft_end(is->rdft);
2810 av_freep(&is->rdft_data);
2815 case AVMEDIA_TYPE_VIDEO:
2816 decoder_abort(&is->viddec, &is->pictq);
2817 decoder_destroy(&is->viddec);
2819 case AVMEDIA_TYPE_SUBTITLE:
2820 decoder_abort(&is->subdec, &is->subpq);
2821 decoder_destroy(&is->subdec);
2827 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2828 avcodec_close(avctx);
2829 switch (avctx->codec_type) {
2830 case AVMEDIA_TYPE_AUDIO:
2831 is->audio_st = NULL;
2832 is->audio_stream = -1;
2834 case AVMEDIA_TYPE_VIDEO:
2835 is->video_st = NULL;
2836 is->video_stream = -1;
2838 case AVMEDIA_TYPE_SUBTITLE:
2839 is->subtitle_st = NULL;
2840 is->subtitle_stream = -1;
2847 static int decode_interrupt_cb(void *ctx)
2849 VideoState *is = ctx;
2850 return is->abort_request;
2853 static int is_realtime(AVFormatContext *s)
2855 if( !strcmp(s->iformat->name, "rtp")
2856 || !strcmp(s->iformat->name, "rtsp")
2857 || !strcmp(s->iformat->name, "sdp")
2861 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2862 || !strncmp(s->filename, "udp:", 4)
2869 /* this thread gets the stream from the disk or the network */
2870 static int read_thread(void *arg)
2872 VideoState *is = arg;
2873 AVFormatContext *ic = NULL;
2875 int st_index[AVMEDIA_TYPE_NB];
2876 AVPacket pkt1, *pkt = &pkt1;
2877 int64_t stream_start_time;
2878 int pkt_in_play_range = 0;
2879 AVDictionaryEntry *t;
2880 AVDictionary **opts;
2881 int orig_nb_streams;
2882 SDL_mutex *wait_mutex = SDL_CreateMutex();
2883 int scan_all_pmts_set = 0;
2886 memset(st_index, -1, sizeof(st_index));
2887 is->last_video_stream = is->video_stream = -1;
2888 is->last_audio_stream = is->audio_stream = -1;
2889 is->last_subtitle_stream = is->subtitle_stream = -1;
2892 ic = avformat_alloc_context();
2894 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2895 ret = AVERROR(ENOMEM);
2898 ic->interrupt_callback.callback = decode_interrupt_cb;
2899 ic->interrupt_callback.opaque = is;
2900 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2901 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2902 scan_all_pmts_set = 1;
2904 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2906 print_error(is->filename, err);
2910 if (scan_all_pmts_set)
2911 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2913 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2914 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2915 ret = AVERROR_OPTION_NOT_FOUND;
2921 ic->flags |= AVFMT_FLAG_GENPTS;
2923 av_format_inject_global_side_data(ic);
2925 opts = setup_find_stream_info_opts(ic, codec_opts);
2926 orig_nb_streams = ic->nb_streams;
2928 err = avformat_find_stream_info(ic, opts);
2930 for (i = 0; i < orig_nb_streams; i++)
2931 av_dict_free(&opts[i]);
2935 av_log(NULL, AV_LOG_WARNING,
2936 "%s: could not find codec parameters\n", is->filename);
2942 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2944 if (seek_by_bytes < 0)
2945 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2947 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2949 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2950 window_title = av_asprintf("%s - %s", t->value, input_filename);
2952 /* if seeking requested, we execute it */
2953 if (start_time != AV_NOPTS_VALUE) {
2956 timestamp = start_time;
2957 /* add the stream start time */
2958 if (ic->start_time != AV_NOPTS_VALUE)
2959 timestamp += ic->start_time;
2960 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2962 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2963 is->filename, (double)timestamp / AV_TIME_BASE);
2967 is->realtime = is_realtime(ic);
2970 av_dump_format(ic, 0, is->filename, 0);
2972 for (i = 0; i < ic->nb_streams; i++) {
2973 AVStream *st = ic->streams[i];
2974 enum AVMediaType type = st->codec->codec_type;
2975 st->discard = AVDISCARD_ALL;
2976 if (wanted_stream_spec[type] && st_index[type] == -1)
2977 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2980 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2981 if (wanted_stream_spec[i] && st_index[i] == -1) {
2982 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));
2983 st_index[i] = INT_MAX;
2988 st_index[AVMEDIA_TYPE_VIDEO] =
2989 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2990 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2992 st_index[AVMEDIA_TYPE_AUDIO] =
2993 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2994 st_index[AVMEDIA_TYPE_AUDIO],
2995 st_index[AVMEDIA_TYPE_VIDEO],
2997 if (!video_disable && !subtitle_disable)
2998 st_index[AVMEDIA_TYPE_SUBTITLE] =
2999 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
3000 st_index[AVMEDIA_TYPE_SUBTITLE],
3001 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
3002 st_index[AVMEDIA_TYPE_AUDIO] :
3003 st_index[AVMEDIA_TYPE_VIDEO]),
3006 is->show_mode = show_mode;
3007 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3008 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
3009 AVCodecContext *avctx = st->codec;
3010 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
3012 set_default_window_size(avctx->width, avctx->height, sar);
3015 /* open the streams */
3016 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
3017 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
3021 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3022 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
3024 if (is->show_mode == SHOW_MODE_NONE)
3025 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
3027 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
3028 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
3031 if (is->video_stream < 0 && is->audio_stream < 0) {
3032 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
3038 if (infinite_buffer < 0 && is->realtime)
3039 infinite_buffer = 1;
3042 if (is->abort_request)
3044 if (is->paused != is->last_paused) {
3045 is->last_paused = is->paused;
3047 is->read_pause_return = av_read_pause(ic);
3051 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3053 (!strcmp(ic->iformat->name, "rtsp") ||
3054 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3055 /* wait 10 ms to avoid trying to get another packet */
3062 int64_t seek_target = is->seek_pos;
3063 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3064 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3065 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3066 // of the seek_pos/seek_rel variables
3068 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3070 av_log(NULL, AV_LOG_ERROR,
3071 "%s: error while seeking\n", is->ic->filename);
3073 if (is->audio_stream >= 0) {
3074 packet_queue_flush(&is->audioq);
3075 packet_queue_put(&is->audioq, &flush_pkt);
3077 if (is->subtitle_stream >= 0) {
3078 packet_queue_flush(&is->subtitleq);
3079 packet_queue_put(&is->subtitleq, &flush_pkt);
3081 if (is->video_stream >= 0) {
3082 packet_queue_flush(&is->videoq);
3083 packet_queue_put(&is->videoq, &flush_pkt);
3085 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3086 set_clock(&is->extclk, NAN, 0);
3088 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3092 is->queue_attachments_req = 1;
3095 step_to_next_frame(is);
3097 if (is->queue_attachments_req) {
3098 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3100 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3102 packet_queue_put(&is->videoq, ©);
3103 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3105 is->queue_attachments_req = 0;
3108 /* if the queue are full, no need to read more */
3109 if (infinite_buffer<1 &&
3110 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3111 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3112 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3113 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3114 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3116 SDL_LockMutex(wait_mutex);
3117 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3118 SDL_UnlockMutex(wait_mutex);
3122 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3123 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3124 if (loop != 1 && (!loop || --loop)) {
3125 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3126 } else if (autoexit) {
3131 ret = av_read_frame(ic, pkt);
3133 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3134 if (is->video_stream >= 0)
3135 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3136 if (is->audio_stream >= 0)
3137 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3138 if (is->subtitle_stream >= 0)
3139 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3142 if (ic->pb && ic->pb->error)
3144 SDL_LockMutex(wait_mutex);
3145 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3146 SDL_UnlockMutex(wait_mutex);
3151 /* check if packet is in play range specified by user, then queue, otherwise discard */
3152 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3153 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3154 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3155 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3156 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3157 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3158 <= ((double)duration / 1000000);
3159 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3160 packet_queue_put(&is->audioq, pkt);
3161 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3162 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3163 packet_queue_put(&is->videoq, pkt);
3164 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3165 packet_queue_put(&is->subtitleq, pkt);
3167 av_free_packet(pkt);
3170 /* wait until the end */
3171 while (!is->abort_request) {
3177 /* close each stream */
3178 if (is->audio_stream >= 0)
3179 stream_component_close(is, is->audio_stream);
3180 if (is->video_stream >= 0)
3181 stream_component_close(is, is->video_stream);
3182 if (is->subtitle_stream >= 0)
3183 stream_component_close(is, is->subtitle_stream);
3185 avformat_close_input(&ic);
3192 event.type = FF_QUIT_EVENT;
3193 event.user.data1 = is;
3194 SDL_PushEvent(&event);
3196 SDL_DestroyMutex(wait_mutex);
3200 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3204 is = av_mallocz(sizeof(VideoState));
3207 av_strlcpy(is->filename, filename, sizeof(is->filename));
3208 is->iformat = iformat;
3212 /* start video display */
3213 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3215 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3217 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3220 packet_queue_init(&is->videoq);
3221 packet_queue_init(&is->audioq);
3222 packet_queue_init(&is->subtitleq);
3224 is->continue_read_thread = SDL_CreateCond();
3226 init_clock(&is->vidclk, &is->videoq.serial);
3227 init_clock(&is->audclk, &is->audioq.serial);
3228 init_clock(&is->extclk, &is->extclk.serial);
3229 is->audio_clock_serial = -1;
3230 is->av_sync_type = av_sync_type;
3231 is->read_tid = SDL_CreateThread(read_thread, is);
3232 if (!is->read_tid) {
3240 static void stream_cycle_channel(VideoState *is, int codec_type)
3242 AVFormatContext *ic = is->ic;
3243 int start_index, stream_index;
3246 AVProgram *p = NULL;
3247 int nb_streams = is->ic->nb_streams;
3249 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3250 start_index = is->last_video_stream;
3251 old_index = is->video_stream;
3252 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3253 start_index = is->last_audio_stream;
3254 old_index = is->audio_stream;
3256 start_index = is->last_subtitle_stream;
3257 old_index = is->subtitle_stream;
3259 stream_index = start_index;
3261 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3262 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3264 nb_streams = p->nb_stream_indexes;
3265 for (start_index = 0; start_index < nb_streams; start_index++)
3266 if (p->stream_index[start_index] == stream_index)
3268 if (start_index == nb_streams)
3270 stream_index = start_index;
3275 if (++stream_index >= nb_streams)
3277 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3280 is->last_subtitle_stream = -1;
3283 if (start_index == -1)
3287 if (stream_index == start_index)
3289 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3290 if (st->codec->codec_type == codec_type) {
3291 /* check that parameters are OK */
3292 switch (codec_type) {
3293 case AVMEDIA_TYPE_AUDIO:
3294 if (st->codec->sample_rate != 0 &&
3295 st->codec->channels != 0)
3298 case AVMEDIA_TYPE_VIDEO:
3299 case AVMEDIA_TYPE_SUBTITLE:
3307 if (p && stream_index != -1)
3308 stream_index = p->stream_index[stream_index];
3309 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3310 av_get_media_type_string(codec_type),
3314 stream_component_close(is, old_index);
3315 stream_component_open(is, stream_index);
3319 static void toggle_full_screen(VideoState *is)
3321 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3322 /* OS X needs to reallocate the SDL overlays */
3324 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3325 is->pictq.queue[i].reallocate = 1;
3327 is_full_screen = !is_full_screen;
3328 video_open(is, 1, NULL);
3331 static void toggle_audio_display(VideoState *is)
3333 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3334 int next = is->show_mode;
3336 next = (next + 1) % SHOW_MODE_NB;
3337 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3338 if (is->show_mode != next) {
3339 fill_rectangle(screen,
3340 is->xleft, is->ytop, is->width, is->height,
3342 is->force_refresh = 1;
3343 is->show_mode = next;
3347 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3348 double remaining_time = 0.0;
3350 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3351 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3355 if (remaining_time > 0.0)
3356 av_usleep((int64_t)(remaining_time * 1000000.0));
3357 remaining_time = REFRESH_RATE;
3358 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3359 video_refresh(is, &remaining_time);
3364 static void seek_chapter(VideoState *is, int incr)
3366 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3369 if (!is->ic->nb_chapters)
3372 /* find the current chapter */
3373 for (i = 0; i < is->ic->nb_chapters; i++) {
3374 AVChapter *ch = is->ic->chapters[i];
3375 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3383 if (i >= is->ic->nb_chapters)
3386 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3387 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3388 AV_TIME_BASE_Q), 0, 0);
3391 /* handle an event sent by the GUI */
3392 static void event_loop(VideoState *cur_stream)
3395 double incr, pos, frac;
3399 refresh_loop_wait_event(cur_stream, &event);
3400 switch (event.type) {
3402 if (exit_on_keydown) {
3403 do_exit(cur_stream);
3406 switch (event.key.keysym.sym) {
3409 do_exit(cur_stream);
3412 toggle_full_screen(cur_stream);
3413 cur_stream->force_refresh = 1;
3417 toggle_pause(cur_stream);
3419 case SDLK_s: // S: Step to next frame
3420 step_to_next_frame(cur_stream);
3423 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3426 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3429 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3430 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3431 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3434 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3438 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3439 if (++cur_stream->vfilter_idx >= nb_vfilters)
3440 cur_stream->vfilter_idx = 0;
3442 cur_stream->vfilter_idx = 0;
3443 toggle_audio_display(cur_stream);
3446 toggle_audio_display(cur_stream);
3450 if (cur_stream->ic->nb_chapters <= 1) {
3454 seek_chapter(cur_stream, 1);
3457 if (cur_stream->ic->nb_chapters <= 1) {
3461 seek_chapter(cur_stream, -1);
3475 if (seek_by_bytes) {
3477 if (pos < 0 && cur_stream->video_stream >= 0)
3478 pos = frame_queue_last_pos(&cur_stream->pictq);
3479 if (pos < 0 && cur_stream->audio_stream >= 0)
3480 pos = frame_queue_last_pos(&cur_stream->sampq);
3482 pos = avio_tell(cur_stream->ic->pb);
3483 if (cur_stream->ic->bit_rate)
3484 incr *= cur_stream->ic->bit_rate / 8.0;
3488 stream_seek(cur_stream, pos, incr, 1);
3490 pos = get_master_clock(cur_stream);
3492 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3494 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3495 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3496 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3503 case SDL_VIDEOEXPOSE:
3504 cur_stream->force_refresh = 1;
3506 case SDL_MOUSEBUTTONDOWN:
3507 if (exit_on_mousedown) {
3508 do_exit(cur_stream);
3511 case SDL_MOUSEMOTION:
3512 if (cursor_hidden) {
3516 cursor_last_shown = av_gettime_relative();
3517 if (event.type == SDL_MOUSEBUTTONDOWN) {
3520 if (event.motion.state != SDL_PRESSED)
3524 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3525 uint64_t size = avio_size(cur_stream->ic->pb);
3526 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3530 int tns, thh, tmm, tss;
3531 tns = cur_stream->ic->duration / 1000000LL;
3533 tmm = (tns % 3600) / 60;
3535 frac = x / cur_stream->width;
3538 mm = (ns % 3600) / 60;
3540 av_log(NULL, AV_LOG_INFO,
3541 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3542 hh, mm, ss, thh, tmm, tss);
3543 ts = frac * cur_stream->ic->duration;
3544 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3545 ts += cur_stream->ic->start_time;
3546 stream_seek(cur_stream, ts, 0, 0);
3549 case SDL_VIDEORESIZE:
3550 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3551 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3553 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3554 do_exit(cur_stream);
3556 screen_width = cur_stream->width = screen->w;
3557 screen_height = cur_stream->height = screen->h;
3558 cur_stream->force_refresh = 1;
3562 do_exit(cur_stream);
3564 case FF_ALLOC_EVENT:
3565 alloc_picture(event.user.data1);
3573 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3575 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3576 return opt_default(NULL, "video_size", arg);
3579 static int opt_width(void *optctx, const char *opt, const char *arg)
3581 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3585 static int opt_height(void *optctx, const char *opt, const char *arg)
3587 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3591 static int opt_format(void *optctx, const char *opt, const char *arg)
3593 file_iformat = av_find_input_format(arg);
3594 if (!file_iformat) {
3595 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3596 return AVERROR(EINVAL);
3601 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3603 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3604 return opt_default(NULL, "pixel_format", arg);
3607 static int opt_sync(void *optctx, const char *opt, const char *arg)
3609 if (!strcmp(arg, "audio"))
3610 av_sync_type = AV_SYNC_AUDIO_MASTER;
3611 else if (!strcmp(arg, "video"))
3612 av_sync_type = AV_SYNC_VIDEO_MASTER;
3613 else if (!strcmp(arg, "ext"))
3614 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3616 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3622 static int opt_seek(void *optctx, const char *opt, const char *arg)
3624 start_time = parse_time_or_die(opt, arg, 1);
3628 static int opt_duration(void *optctx, const char *opt, const char *arg)
3630 duration = parse_time_or_die(opt, arg, 1);
3634 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3636 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3637 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3638 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3639 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3643 static void opt_input_file(void *optctx, const char *filename)
3645 if (input_filename) {
3646 av_log(NULL, AV_LOG_FATAL,
3647 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3648 filename, input_filename);
3651 if (!strcmp(filename, "-"))
3653 input_filename = filename;
3656 static int opt_codec(void *optctx, const char *opt, const char *arg)
3658 const char *spec = strchr(opt, ':');
3660 av_log(NULL, AV_LOG_ERROR,
3661 "No media specifier was specified in '%s' in option '%s'\n",
3663 return AVERROR(EINVAL);
3667 case 'a' : audio_codec_name = arg; break;
3668 case 's' : subtitle_codec_name = arg; break;
3669 case 'v' : video_codec_name = arg; break;
3671 av_log(NULL, AV_LOG_ERROR,
3672 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3673 return AVERROR(EINVAL);
3680 static const OptionDef options[] = {
3681 #include "cmdutils_common_opts.h"
3682 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3683 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3684 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3685 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3686 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3687 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3688 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3689 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3690 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3691 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3692 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3693 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3694 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3695 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3696 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3697 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3698 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3699 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3700 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3701 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3702 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3703 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3704 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3705 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3706 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3707 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3708 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3709 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3710 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3712 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3713 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3715 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3716 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3717 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3718 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3719 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3720 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3721 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3722 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3723 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3727 static void show_usage(void)
3729 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3730 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3731 av_log(NULL, AV_LOG_INFO, "\n");
3734 void show_help_default(const char *opt, const char *arg)
3736 av_log_set_callback(log_callback_help);
3738 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3739 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3741 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3742 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3743 #if !CONFIG_AVFILTER
3744 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3746 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3748 printf("\nWhile playing:\n"
3750 "f toggle full screen\n"
3752 "a cycle audio channel in the current program\n"
3753 "v cycle video channel\n"
3754 "t cycle subtitle channel in the current program\n"
3756 "w cycle video filters or show modes\n"
3757 "s activate frame-step mode\n"
3758 "left/right seek backward/forward 10 seconds\n"
3759 "down/up seek backward/forward 1 minute\n"
3760 "page down/page up seek backward/forward 10 minutes\n"
3761 "mouse click seek to percentage in file corresponding to fraction of width\n"
3765 static int lockmgr(void **mtx, enum AVLockOp op)
3768 case AV_LOCK_CREATE:
3769 *mtx = SDL_CreateMutex();
3773 case AV_LOCK_OBTAIN:
3774 return !!SDL_LockMutex(*mtx);
3775 case AV_LOCK_RELEASE:
3776 return !!SDL_UnlockMutex(*mtx);
3777 case AV_LOCK_DESTROY:
3778 SDL_DestroyMutex(*mtx);
3784 /* Called from the main */
3785 int main(int argc, char **argv)
3789 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3791 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3792 parse_loglevel(argc, argv, options);
3794 /* register all codecs, demux and protocols */
3796 avdevice_register_all();
3799 avfilter_register_all();
3802 avformat_network_init();
3806 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3807 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3809 show_banner(argc, argv, options);
3811 parse_options(NULL, argc, argv, options, opt_input_file);
3813 if (!input_filename) {
3815 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3816 av_log(NULL, AV_LOG_FATAL,
3817 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3821 if (display_disable) {
3824 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3826 flags &= ~SDL_INIT_AUDIO;
3827 if (display_disable)
3828 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3829 #if !defined(_WIN32) && !defined(__APPLE__)
3830 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3832 if (SDL_Init (flags)) {
3833 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3834 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3838 if (!display_disable) {
3839 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3840 fs_screen_width = vi->current_w;
3841 fs_screen_height = vi->current_h;
3844 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3845 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3846 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3848 if (av_lockmgr_register(lockmgr)) {
3849 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3853 av_init_packet(&flush_pkt);
3854 flush_pkt.data = (uint8_t *)&flush_pkt;
3856 is = stream_open(input_filename, file_iformat);
3858 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");