2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/colorspace.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avcodec.h"
52 # include "libavfilter/avfilter.h"
53 # include "libavfilter/buffersink.h"
54 # include "libavfilter/buffersrc.h"
58 #include <SDL_thread.h>
64 const char program_name[] = "ffplay";
65 const int program_birth_year = 2003;
67 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
70 /* Minimum SDL audio buffer size, in samples. */
71 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
72 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
73 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
75 /* no AV sync correction is done if below the minimum AV sync threshold */
76 #define AV_SYNC_THRESHOLD_MIN 0.04
77 /* AV sync correction is done if above the maximum AV sync threshold */
78 #define AV_SYNC_THRESHOLD_MAX 0.1
79 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
80 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
81 /* no AV correction is done if too big error */
82 #define AV_NOSYNC_THRESHOLD 10.0
84 /* maximum audio speed change to get correct sync */
85 #define SAMPLE_CORRECTION_PERCENT_MAX 10
87 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
88 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
89 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
90 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
92 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
93 #define AUDIO_DIFF_AVG_NB 20
95 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
96 #define REFRESH_RATE 0.01
98 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
99 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
100 #define SAMPLE_ARRAY_SIZE (8 * 65536)
102 #define CURSOR_HIDE_DELAY 1000000
104 static int64_t sws_flags = SWS_BICUBIC;
106 typedef struct MyAVPacketList {
108 struct MyAVPacketList *next;
112 typedef struct PacketQueue {
113 MyAVPacketList *first_pkt, *last_pkt;
122 #define VIDEO_PICTURE_QUEUE_SIZE 3
123 #define SUBPICTURE_QUEUE_SIZE 16
124 #define SAMPLE_QUEUE_SIZE 9
125 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
127 typedef struct AudioParams {
130 int64_t channel_layout;
131 enum AVSampleFormat fmt;
136 typedef struct Clock {
137 double pts; /* clock base */
138 double pts_drift; /* clock base minus time at which we updated the clock */
141 int serial; /* clock is based on a packet with this serial */
143 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
146 /* Common struct for handling all types of decoded data and allocated render buffers. */
147 typedef struct Frame {
151 double pts; /* presentation timestamp for the frame */
152 double duration; /* estimated duration of the frame */
153 int64_t pos; /* byte position of the frame in the input file */
162 typedef struct FrameQueue {
163 Frame queue[FRAME_QUEUE_SIZE];
176 AV_SYNC_AUDIO_MASTER, /* default choice */
177 AV_SYNC_VIDEO_MASTER,
178 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
181 typedef struct Decoder {
185 AVCodecContext *avctx;
189 SDL_cond *empty_queue_cond;
191 AVRational start_pts_tb;
193 AVRational next_pts_tb;
194 SDL_Thread *decoder_tid;
197 typedef struct VideoState {
198 SDL_Thread *read_tid;
199 AVInputFormat *iformat;
204 int queue_attachments_req;
209 int read_pause_return;
230 int audio_clock_serial;
231 double audio_diff_cum; /* used for AV difference average computation */
232 double audio_diff_avg_coef;
233 double audio_diff_threshold;
234 int audio_diff_avg_count;
237 int audio_hw_buf_size;
238 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
241 unsigned int audio_buf_size; /* in bytes */
242 unsigned int audio_buf1_size;
243 int audio_buf_index; /* in bytes */
244 int audio_write_buf_size;
245 struct AudioParams audio_src;
247 struct AudioParams audio_filter_src;
249 struct AudioParams audio_tgt;
250 struct SwrContext *swr_ctx;
251 int frame_drops_early;
252 int frame_drops_late;
255 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
257 int16_t sample_array[SAMPLE_ARRAY_SIZE];
258 int sample_array_index;
262 FFTSample *rdft_data;
264 double last_vis_time;
267 AVStream *subtitle_st;
268 PacketQueue subtitleq;
271 double frame_last_returned_time;
272 double frame_last_filter_delay;
276 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
278 struct SwsContext *img_convert_ctx;
280 SDL_Rect last_display_rect;
284 int width, height, xleft, ytop;
289 AVFilterContext *in_video_filter; // the first filter in the video chain
290 AVFilterContext *out_video_filter; // the last filter in the video chain
291 AVFilterContext *in_audio_filter; // the first filter in the audio chain
292 AVFilterContext *out_audio_filter; // the last filter in the audio chain
293 AVFilterGraph *agraph; // audio filter graph
296 int last_video_stream, last_audio_stream, last_subtitle_stream;
298 SDL_cond *continue_read_thread;
301 /* options specified by the user */
302 static AVInputFormat *file_iformat;
303 static const char *input_filename;
304 static const char *window_title;
305 static int fs_screen_width;
306 static int fs_screen_height;
307 static int default_width = 640;
308 static int default_height = 480;
309 static int screen_width = 0;
310 static int screen_height = 0;
311 static int audio_disable;
312 static int video_disable;
313 static int subtitle_disable;
314 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
315 static int seek_by_bytes = -1;
316 static int display_disable;
317 static int show_status = 1;
318 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
319 static int64_t start_time = AV_NOPTS_VALUE;
320 static int64_t duration = AV_NOPTS_VALUE;
322 static int genpts = 0;
323 static int lowres = 0;
324 static int decoder_reorder_pts = -1;
326 static int exit_on_keydown;
327 static int exit_on_mousedown;
329 static int framedrop = -1;
330 static int infinite_buffer = -1;
331 static enum ShowMode show_mode = SHOW_MODE_NONE;
332 static const char *audio_codec_name;
333 static const char *subtitle_codec_name;
334 static const char *video_codec_name;
335 double rdftspeed = 0.02;
336 static int64_t cursor_last_shown;
337 static int cursor_hidden = 0;
339 static const char **vfilters_list = NULL;
340 static int nb_vfilters = 0;
341 static char *afilters = NULL;
343 static int autorotate = 1;
345 /* current context */
346 static int is_full_screen;
347 static int64_t audio_callback_time;
349 static AVPacket flush_pkt;
351 #define FF_ALLOC_EVENT (SDL_USEREVENT)
352 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
354 static SDL_Surface *screen;
357 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
359 GROW_ARRAY(vfilters_list, nb_vfilters);
360 vfilters_list[nb_vfilters - 1] = arg;
366 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
367 enum AVSampleFormat fmt2, int64_t channel_count2)
369 /* If channel count == 1, planar and non-planar formats are the same */
370 if (channel_count1 == 1 && channel_count2 == 1)
371 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
373 return channel_count1 != channel_count2 || fmt1 != fmt2;
377 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
379 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
380 return channel_layout;
385 static void free_picture(Frame *vp);
387 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
389 MyAVPacketList *pkt1;
391 if (q->abort_request)
394 pkt1 = av_malloc(sizeof(MyAVPacketList));
399 if (pkt == &flush_pkt)
401 pkt1->serial = q->serial;
406 q->last_pkt->next = pkt1;
409 q->size += pkt1->pkt.size + sizeof(*pkt1);
410 /* XXX: should duplicate packet data in DV case */
411 SDL_CondSignal(q->cond);
415 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
419 /* duplicate the packet */
420 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
423 SDL_LockMutex(q->mutex);
424 ret = packet_queue_put_private(q, pkt);
425 SDL_UnlockMutex(q->mutex);
427 if (pkt != &flush_pkt && ret < 0)
433 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
435 AVPacket pkt1, *pkt = &pkt1;
439 pkt->stream_index = stream_index;
440 return packet_queue_put(q, pkt);
443 /* packet queue handling */
444 static void packet_queue_init(PacketQueue *q)
446 memset(q, 0, sizeof(PacketQueue));
447 q->mutex = SDL_CreateMutex();
448 q->cond = SDL_CreateCond();
449 q->abort_request = 1;
452 static void packet_queue_flush(PacketQueue *q)
454 MyAVPacketList *pkt, *pkt1;
456 SDL_LockMutex(q->mutex);
457 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
459 av_free_packet(&pkt->pkt);
466 SDL_UnlockMutex(q->mutex);
469 static void packet_queue_destroy(PacketQueue *q)
471 packet_queue_flush(q);
472 SDL_DestroyMutex(q->mutex);
473 SDL_DestroyCond(q->cond);
476 static void packet_queue_abort(PacketQueue *q)
478 SDL_LockMutex(q->mutex);
480 q->abort_request = 1;
482 SDL_CondSignal(q->cond);
484 SDL_UnlockMutex(q->mutex);
487 static void packet_queue_start(PacketQueue *q)
489 SDL_LockMutex(q->mutex);
490 q->abort_request = 0;
491 packet_queue_put_private(q, &flush_pkt);
492 SDL_UnlockMutex(q->mutex);
495 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
496 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
498 MyAVPacketList *pkt1;
501 SDL_LockMutex(q->mutex);
504 if (q->abort_request) {
511 q->first_pkt = pkt1->next;
515 q->size -= pkt1->pkt.size + sizeof(*pkt1);
518 *serial = pkt1->serial;
526 SDL_CondWait(q->cond, q->mutex);
529 SDL_UnlockMutex(q->mutex);
533 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
534 memset(d, 0, sizeof(Decoder));
537 d->empty_queue_cond = empty_queue_cond;
538 d->start_pts = AV_NOPTS_VALUE;
541 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
547 if (d->queue->abort_request)
550 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
553 if (d->queue->nb_packets == 0)
554 SDL_CondSignal(d->empty_queue_cond);
555 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
557 if (pkt.data == flush_pkt.data) {
558 avcodec_flush_buffers(d->avctx);
560 d->next_pts = d->start_pts;
561 d->next_pts_tb = d->start_pts_tb;
563 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
564 av_free_packet(&d->pkt);
565 d->pkt_temp = d->pkt = pkt;
566 d->packet_pending = 1;
569 switch (d->avctx->codec_type) {
570 case AVMEDIA_TYPE_VIDEO:
571 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
573 if (decoder_reorder_pts == -1) {
574 frame->pts = av_frame_get_best_effort_timestamp(frame);
575 } else if (decoder_reorder_pts) {
576 frame->pts = frame->pkt_pts;
578 frame->pts = frame->pkt_dts;
582 case AVMEDIA_TYPE_AUDIO:
583 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
585 AVRational tb = (AVRational){1, frame->sample_rate};
586 if (frame->pts != AV_NOPTS_VALUE)
587 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
588 else if (frame->pkt_pts != AV_NOPTS_VALUE)
589 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
590 else if (d->next_pts != AV_NOPTS_VALUE)
591 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
592 if (frame->pts != AV_NOPTS_VALUE) {
593 d->next_pts = frame->pts + frame->nb_samples;
598 case AVMEDIA_TYPE_SUBTITLE:
599 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
604 d->packet_pending = 0;
607 d->pkt_temp.pts = AV_NOPTS_VALUE;
608 if (d->pkt_temp.data) {
609 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
610 ret = d->pkt_temp.size;
611 d->pkt_temp.data += ret;
612 d->pkt_temp.size -= ret;
613 if (d->pkt_temp.size <= 0)
614 d->packet_pending = 0;
617 d->packet_pending = 0;
618 d->finished = d->pkt_serial;
622 } while (!got_frame && !d->finished);
627 static void decoder_destroy(Decoder *d) {
628 av_free_packet(&d->pkt);
631 static void frame_queue_unref_item(Frame *vp)
633 av_frame_unref(vp->frame);
634 avsubtitle_free(&vp->sub);
637 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
640 memset(f, 0, sizeof(FrameQueue));
641 if (!(f->mutex = SDL_CreateMutex()))
642 return AVERROR(ENOMEM);
643 if (!(f->cond = SDL_CreateCond()))
644 return AVERROR(ENOMEM);
646 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
647 f->keep_last = !!keep_last;
648 for (i = 0; i < f->max_size; i++)
649 if (!(f->queue[i].frame = av_frame_alloc()))
650 return AVERROR(ENOMEM);
654 static void frame_queue_destory(FrameQueue *f)
657 for (i = 0; i < f->max_size; i++) {
658 Frame *vp = &f->queue[i];
659 frame_queue_unref_item(vp);
660 av_frame_free(&vp->frame);
663 SDL_DestroyMutex(f->mutex);
664 SDL_DestroyCond(f->cond);
667 static void frame_queue_signal(FrameQueue *f)
669 SDL_LockMutex(f->mutex);
670 SDL_CondSignal(f->cond);
671 SDL_UnlockMutex(f->mutex);
674 static Frame *frame_queue_peek(FrameQueue *f)
676 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
679 static Frame *frame_queue_peek_next(FrameQueue *f)
681 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
684 static Frame *frame_queue_peek_last(FrameQueue *f)
686 return &f->queue[f->rindex];
689 static Frame *frame_queue_peek_writable(FrameQueue *f)
691 /* wait until we have space to put a new frame */
692 SDL_LockMutex(f->mutex);
693 while (f->size >= f->max_size &&
694 !f->pktq->abort_request) {
695 SDL_CondWait(f->cond, f->mutex);
697 SDL_UnlockMutex(f->mutex);
699 if (f->pktq->abort_request)
702 return &f->queue[f->windex];
705 static Frame *frame_queue_peek_readable(FrameQueue *f)
707 /* wait until we have a readable a new frame */
708 SDL_LockMutex(f->mutex);
709 while (f->size - f->rindex_shown <= 0 &&
710 !f->pktq->abort_request) {
711 SDL_CondWait(f->cond, f->mutex);
713 SDL_UnlockMutex(f->mutex);
715 if (f->pktq->abort_request)
718 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
721 static void frame_queue_push(FrameQueue *f)
723 if (++f->windex == f->max_size)
725 SDL_LockMutex(f->mutex);
727 SDL_CondSignal(f->cond);
728 SDL_UnlockMutex(f->mutex);
731 static void frame_queue_next(FrameQueue *f)
733 if (f->keep_last && !f->rindex_shown) {
737 frame_queue_unref_item(&f->queue[f->rindex]);
738 if (++f->rindex == f->max_size)
740 SDL_LockMutex(f->mutex);
742 SDL_CondSignal(f->cond);
743 SDL_UnlockMutex(f->mutex);
746 /* jump back to the previous frame if available by resetting rindex_shown */
747 static int frame_queue_prev(FrameQueue *f)
749 int ret = f->rindex_shown;
754 /* return the number of undisplayed frames in the queue */
755 static int frame_queue_nb_remaining(FrameQueue *f)
757 return f->size - f->rindex_shown;
760 /* return last shown position */
761 static int64_t frame_queue_last_pos(FrameQueue *f)
763 Frame *fp = &f->queue[f->rindex];
764 if (f->rindex_shown && fp->serial == f->pktq->serial)
770 static void decoder_abort(Decoder *d, FrameQueue *fq)
772 packet_queue_abort(d->queue);
773 frame_queue_signal(fq);
774 SDL_WaitThread(d->decoder_tid, NULL);
775 d->decoder_tid = NULL;
776 packet_queue_flush(d->queue);
779 static inline void fill_rectangle(SDL_Surface *screen,
780 int x, int y, int w, int h, int color, int update)
787 SDL_FillRect(screen, &rect, color);
788 if (update && w > 0 && h > 0)
789 SDL_UpdateRect(screen, x, y, w, h);
792 /* draw only the border of a rectangle */
793 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
797 /* fill the background */
801 w2 = width - (x + w);
807 h2 = height - (y + h);
810 fill_rectangle(screen,
814 fill_rectangle(screen,
815 xleft + width - w2, ytop,
818 fill_rectangle(screen,
822 fill_rectangle(screen,
823 xleft + w1, ytop + height - h2,
828 #define ALPHA_BLEND(a, oldp, newp, s)\
829 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
831 #define RGBA_IN(r, g, b, a, s)\
833 unsigned int v = ((const uint32_t *)(s))[0];\
834 a = (v >> 24) & 0xff;\
835 r = (v >> 16) & 0xff;\
836 g = (v >> 8) & 0xff;\
840 #define YUVA_IN(y, u, v, a, s, pal)\
842 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
843 a = (val >> 24) & 0xff;\
844 y = (val >> 16) & 0xff;\
845 u = (val >> 8) & 0xff;\
849 #define YUVA_OUT(d, y, u, v, a)\
851 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
857 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
859 int wrap, wrap3, width2, skip2;
860 int y, u, v, a, u1, v1, a1, w, h;
861 uint8_t *lum, *cb, *cr;
864 int dstx, dsty, dstw, dsth;
866 dstw = av_clip(rect->w, 0, imgw);
867 dsth = av_clip(rect->h, 0, imgh);
868 dstx = av_clip(rect->x, 0, imgw - dstw);
869 dsty = av_clip(rect->y, 0, imgh - dsth);
870 lum = dst->data[0] + dsty * dst->linesize[0];
871 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
872 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
874 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
876 wrap = dst->linesize[0];
877 wrap3 = rect->pict.linesize[0];
878 p = rect->pict.data[0];
879 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
887 YUVA_IN(y, u, v, a, p, pal);
888 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
889 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
890 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
896 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
897 YUVA_IN(y, u, v, a, p, pal);
901 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
903 YUVA_IN(y, u, v, a, p + BPP, pal);
907 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
908 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
909 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
916 YUVA_IN(y, u, v, a, p, pal);
917 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
918 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
919 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
923 p += wrap3 - dstw * BPP;
924 lum += wrap - dstw - dstx;
925 cb += dst->linesize[1] - width2 - skip2;
926 cr += dst->linesize[2] - width2 - skip2;
928 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
934 YUVA_IN(y, u, v, a, p, pal);
938 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
941 YUVA_IN(y, u, v, a, p, pal);
945 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
946 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
947 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
953 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
954 YUVA_IN(y, u, v, a, p, pal);
958 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
960 YUVA_IN(y, u, v, a, p + BPP, pal);
964 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
968 YUVA_IN(y, u, v, a, p, pal);
972 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
974 YUVA_IN(y, u, v, a, p + BPP, pal);
978 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
980 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
981 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
985 p += -wrap3 + 2 * BPP;
989 YUVA_IN(y, u, v, a, p, pal);
993 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
996 YUVA_IN(y, u, v, a, p, pal);
1000 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1001 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
1002 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
1008 p += wrap3 + (wrap3 - dstw * BPP);
1009 lum += wrap + (wrap - dstw - dstx);
1010 cb += dst->linesize[1] - width2 - skip2;
1011 cr += dst->linesize[2] - width2 - skip2;
1013 /* handle odd height */
1020 YUVA_IN(y, u, v, a, p, pal);
1021 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1022 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1023 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1029 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
1030 YUVA_IN(y, u, v, a, p, pal);
1034 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1036 YUVA_IN(y, u, v, a, p + BPP, pal);
1040 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
1041 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
1042 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
1049 YUVA_IN(y, u, v, a, p, pal);
1050 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1051 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1052 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1057 static void free_picture(Frame *vp)
1060 SDL_FreeYUVOverlay(vp->bmp);
1065 static void calculate_display_rect(SDL_Rect *rect,
1066 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
1067 int pic_width, int pic_height, AVRational pic_sar)
1070 int width, height, x, y;
1072 if (pic_sar.num == 0)
1075 aspect_ratio = av_q2d(pic_sar);
1077 if (aspect_ratio <= 0.0)
1079 aspect_ratio *= (float)pic_width / (float)pic_height;
1081 /* XXX: we suppose the screen has a 1.0 pixel ratio */
1082 height = scr_height;
1083 width = ((int)rint(height * aspect_ratio)) & ~1;
1084 if (width > scr_width) {
1086 height = ((int)rint(width / aspect_ratio)) & ~1;
1088 x = (scr_width - width) / 2;
1089 y = (scr_height - height) / 2;
1090 rect->x = scr_xleft + x;
1091 rect->y = scr_ytop + y;
1092 rect->w = FFMAX(width, 1);
1093 rect->h = FFMAX(height, 1);
1096 static void video_image_display(VideoState *is)
1104 vp = frame_queue_peek(&is->pictq);
1106 if (is->subtitle_st) {
1107 if (frame_queue_nb_remaining(&is->subpq) > 0) {
1108 sp = frame_queue_peek(&is->subpq);
1110 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
1111 SDL_LockYUVOverlay (vp->bmp);
1113 pict.data[0] = vp->bmp->pixels[0];
1114 pict.data[1] = vp->bmp->pixels[2];
1115 pict.data[2] = vp->bmp->pixels[1];
1117 pict.linesize[0] = vp->bmp->pitches[0];
1118 pict.linesize[1] = vp->bmp->pitches[2];
1119 pict.linesize[2] = vp->bmp->pitches[1];
1121 for (i = 0; i < sp->sub.num_rects; i++)
1122 blend_subrect(&pict, sp->sub.rects[i],
1123 vp->bmp->w, vp->bmp->h);
1125 SDL_UnlockYUVOverlay (vp->bmp);
1130 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1132 SDL_DisplayYUVOverlay(vp->bmp, &rect);
1134 if (rect.x != is->last_display_rect.x || rect.y != is->last_display_rect.y || rect.w != is->last_display_rect.w || rect.h != is->last_display_rect.h || is->force_refresh) {
1135 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1136 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
1137 is->last_display_rect = rect;
1142 static inline int compute_mod(int a, int b)
1144 return a < 0 ? a%b + b : a%b;
1147 static void video_audio_display(VideoState *s)
1149 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1150 int ch, channels, h, h2, bgcolor, fgcolor;
1152 int rdft_bits, nb_freq;
1154 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1156 nb_freq = 1 << (rdft_bits - 1);
1158 /* compute display index : center on currently output samples */
1159 channels = s->audio_tgt.channels;
1160 nb_display_channels = channels;
1162 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1164 delay = s->audio_write_buf_size;
1167 /* to be more precise, we take into account the time spent since
1168 the last buffer computation */
1169 if (audio_callback_time) {
1170 time_diff = av_gettime_relative() - audio_callback_time;
1171 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1174 delay += 2 * data_used;
1175 if (delay < data_used)
1178 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1179 if (s->show_mode == SHOW_MODE_WAVES) {
1181 for (i = 0; i < 1000; i += channels) {
1182 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1183 int a = s->sample_array[idx];
1184 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1185 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1186 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1188 if (h < score && (b ^ c) < 0) {
1195 s->last_i_start = i_start;
1197 i_start = s->last_i_start;
1200 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1201 if (s->show_mode == SHOW_MODE_WAVES) {
1202 fill_rectangle(screen,
1203 s->xleft, s->ytop, s->width, s->height,
1206 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1208 /* total height for one channel */
1209 h = s->height / nb_display_channels;
1210 /* graph height / 2 */
1212 for (ch = 0; ch < nb_display_channels; ch++) {
1214 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1215 for (x = 0; x < s->width; x++) {
1216 y = (s->sample_array[i] * h2) >> 15;
1223 fill_rectangle(screen,
1224 s->xleft + x, ys, 1, y,
1227 if (i >= SAMPLE_ARRAY_SIZE)
1228 i -= SAMPLE_ARRAY_SIZE;
1232 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1234 for (ch = 1; ch < nb_display_channels; ch++) {
1235 y = s->ytop + ch * h;
1236 fill_rectangle(screen,
1237 s->xleft, y, s->width, 1,
1240 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1242 nb_display_channels= FFMIN(nb_display_channels, 2);
1243 if (rdft_bits != s->rdft_bits) {
1244 av_rdft_end(s->rdft);
1245 av_free(s->rdft_data);
1246 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1247 s->rdft_bits = rdft_bits;
1248 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1252 for (ch = 0; ch < nb_display_channels; ch++) {
1253 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1255 for (x = 0; x < 2 * nb_freq; x++) {
1256 double w = (x-nb_freq) * (1.0 / nb_freq);
1257 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1259 if (i >= SAMPLE_ARRAY_SIZE)
1260 i -= SAMPLE_ARRAY_SIZE;
1262 av_rdft_calc(s->rdft, data[ch]);
1264 /* Least efficient way to do this, we should of course
1265 * directly access it but it is more than fast enough. */
1266 for (y = 0; y < s->height; y++) {
1267 double w = 1 / sqrt(nb_freq);
1268 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
1269 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1270 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1273 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1275 fill_rectangle(screen,
1276 s->xpos, s->height-y, 1, 1,
1280 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1283 if (s->xpos >= s->width)
1288 static void stream_close(VideoState *is)
1290 /* XXX: use a special url_shutdown call to abort parse cleanly */
1291 is->abort_request = 1;
1292 SDL_WaitThread(is->read_tid, NULL);
1293 packet_queue_destroy(&is->videoq);
1294 packet_queue_destroy(&is->audioq);
1295 packet_queue_destroy(&is->subtitleq);
1297 /* free all pictures */
1298 frame_queue_destory(&is->pictq);
1299 frame_queue_destory(&is->sampq);
1300 frame_queue_destory(&is->subpq);
1301 SDL_DestroyCond(is->continue_read_thread);
1302 #if !CONFIG_AVFILTER
1303 sws_freeContext(is->img_convert_ctx);
1308 static void do_exit(VideoState *is)
1313 av_lockmgr_register(NULL);
1316 av_freep(&vfilters_list);
1318 avformat_network_deinit();
1322 av_log(NULL, AV_LOG_QUIET, "%s", "");
1326 static void sigterm_handler(int sig)
1331 static void set_default_window_size(int width, int height, AVRational sar)
1334 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1335 default_width = rect.w;
1336 default_height = rect.h;
1339 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1341 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1344 if (is_full_screen) flags |= SDL_FULLSCREEN;
1345 else flags |= SDL_RESIZABLE;
1347 if (vp && vp->width)
1348 set_default_window_size(vp->width, vp->height, vp->sar);
1350 if (is_full_screen && fs_screen_width) {
1351 w = fs_screen_width;
1352 h = fs_screen_height;
1353 } else if (!is_full_screen && screen_width) {
1360 w = FFMIN(16383, w);
1361 if (screen && is->width == screen->w && screen->w == w
1362 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1364 screen = SDL_SetVideoMode(w, h, 0, flags);
1366 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1370 window_title = input_filename;
1371 SDL_WM_SetCaption(window_title, window_title);
1373 is->width = screen->w;
1374 is->height = screen->h;
1379 /* display the current picture, if any */
1380 static void video_display(VideoState *is)
1383 video_open(is, 0, NULL);
1384 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1385 video_audio_display(is);
1386 else if (is->video_st)
1387 video_image_display(is);
1390 static double get_clock(Clock *c)
1392 if (*c->queue_serial != c->serial)
1397 double time = av_gettime_relative() / 1000000.0;
1398 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1402 static void set_clock_at(Clock *c, double pts, int serial, double time)
1405 c->last_updated = time;
1406 c->pts_drift = c->pts - time;
1410 static void set_clock(Clock *c, double pts, int serial)
1412 double time = av_gettime_relative() / 1000000.0;
1413 set_clock_at(c, pts, serial, time);
1416 static void set_clock_speed(Clock *c, double speed)
1418 set_clock(c, get_clock(c), c->serial);
1422 static void init_clock(Clock *c, int *queue_serial)
1426 c->queue_serial = queue_serial;
1427 set_clock(c, NAN, -1);
1430 static void sync_clock_to_slave(Clock *c, Clock *slave)
1432 double clock = get_clock(c);
1433 double slave_clock = get_clock(slave);
1434 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1435 set_clock(c, slave_clock, slave->serial);
1438 static int get_master_sync_type(VideoState *is) {
1439 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1441 return AV_SYNC_VIDEO_MASTER;
1443 return AV_SYNC_AUDIO_MASTER;
1444 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1446 return AV_SYNC_AUDIO_MASTER;
1448 return AV_SYNC_EXTERNAL_CLOCK;
1450 return AV_SYNC_EXTERNAL_CLOCK;
1454 /* get the current master clock value */
1455 static double get_master_clock(VideoState *is)
1459 switch (get_master_sync_type(is)) {
1460 case AV_SYNC_VIDEO_MASTER:
1461 val = get_clock(&is->vidclk);
1463 case AV_SYNC_AUDIO_MASTER:
1464 val = get_clock(&is->audclk);
1467 val = get_clock(&is->extclk);
1473 static void check_external_clock_speed(VideoState *is) {
1474 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1475 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1476 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1477 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1478 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1479 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1481 double speed = is->extclk.speed;
1483 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1487 /* seek in the stream */
1488 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1490 if (!is->seek_req) {
1493 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1495 is->seek_flags |= AVSEEK_FLAG_BYTE;
1497 SDL_CondSignal(is->continue_read_thread);
1501 /* pause or resume the video */
1502 static void stream_toggle_pause(VideoState *is)
1505 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1506 if (is->read_pause_return != AVERROR(ENOSYS)) {
1507 is->vidclk.paused = 0;
1509 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1511 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1512 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1515 static void toggle_pause(VideoState *is)
1517 stream_toggle_pause(is);
1521 static void step_to_next_frame(VideoState *is)
1523 /* if the stream is paused unpause it, then step */
1525 stream_toggle_pause(is);
1529 static double compute_target_delay(double delay, VideoState *is)
1531 double sync_threshold, diff;
1533 /* update delay to follow master synchronisation source */
1534 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1535 /* if video is slave, we try to correct big delays by
1536 duplicating or deleting a frame */
1537 diff = get_clock(&is->vidclk) - get_master_clock(is);
1539 /* skip or repeat frame. We take into account the
1540 delay to compute the threshold. I still don't know
1541 if it is the best guess */
1542 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1543 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1544 if (diff <= -sync_threshold)
1545 delay = FFMAX(0, delay + diff);
1546 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1547 delay = delay + diff;
1548 else if (diff >= sync_threshold)
1553 av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1559 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1560 if (vp->serial == nextvp->serial) {
1561 double duration = nextvp->pts - vp->pts;
1562 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1563 return vp->duration;
1571 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1572 /* update current video pts */
1573 set_clock(&is->vidclk, pts, serial);
1574 sync_clock_to_slave(&is->extclk, &is->vidclk);
1577 /* called to display each frame */
1578 static void video_refresh(void *opaque, double *remaining_time)
1580 VideoState *is = opaque;
1585 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1586 check_external_clock_speed(is);
1588 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1589 time = av_gettime_relative() / 1000000.0;
1590 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1592 is->last_vis_time = time;
1594 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1599 if (is->force_refresh)
1600 redisplay = frame_queue_prev(&is->pictq);
1602 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1603 // nothing to do, no picture to display in the queue
1605 double last_duration, duration, delay;
1608 /* dequeue the picture */
1609 lastvp = frame_queue_peek_last(&is->pictq);
1610 vp = frame_queue_peek(&is->pictq);
1612 if (vp->serial != is->videoq.serial) {
1613 frame_queue_next(&is->pictq);
1618 if (lastvp->serial != vp->serial && !redisplay)
1619 is->frame_timer = av_gettime_relative() / 1000000.0;
1624 /* compute nominal last_duration */
1625 last_duration = vp_duration(is, lastvp, vp);
1629 delay = compute_target_delay(last_duration, is);
1631 time= av_gettime_relative()/1000000.0;
1632 if (time < is->frame_timer + delay && !redisplay) {
1633 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1637 is->frame_timer += delay;
1638 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1639 is->frame_timer = time;
1641 SDL_LockMutex(is->pictq.mutex);
1642 if (!redisplay && !isnan(vp->pts))
1643 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1644 SDL_UnlockMutex(is->pictq.mutex);
1646 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1647 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1648 duration = vp_duration(is, vp, nextvp);
1649 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1651 is->frame_drops_late++;
1652 frame_queue_next(&is->pictq);
1658 if (is->subtitle_st) {
1659 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1660 sp = frame_queue_peek(&is->subpq);
1662 if (frame_queue_nb_remaining(&is->subpq) > 1)
1663 sp2 = frame_queue_peek_next(&is->subpq);
1667 if (sp->serial != is->subtitleq.serial
1668 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1669 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1671 frame_queue_next(&is->subpq);
1679 /* display picture */
1680 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1683 frame_queue_next(&is->pictq);
1685 if (is->step && !is->paused)
1686 stream_toggle_pause(is);
1689 is->force_refresh = 0;
1691 static int64_t last_time;
1693 int aqsize, vqsize, sqsize;
1696 cur_time = av_gettime_relative();
1697 if (!last_time || (cur_time - last_time) >= 30000) {
1702 aqsize = is->audioq.size;
1704 vqsize = is->videoq.size;
1705 if (is->subtitle_st)
1706 sqsize = is->subtitleq.size;
1708 if (is->audio_st && is->video_st)
1709 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1710 else if (is->video_st)
1711 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1712 else if (is->audio_st)
1713 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1714 av_log(NULL, AV_LOG_INFO,
1715 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1716 get_master_clock(is),
1717 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1719 is->frame_drops_early + is->frame_drops_late,
1723 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1724 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1726 last_time = cur_time;
1731 /* allocate a picture (needs to do that in main thread to avoid
1732 potential locking problems */
1733 static void alloc_picture(VideoState *is)
1738 vp = &is->pictq.queue[is->pictq.windex];
1742 video_open(is, 0, vp);
1744 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1747 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1748 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1749 /* SDL allocates a buffer smaller than requested if the video
1750 * overlay hardware is unable to support the requested size. */
1751 av_log(NULL, AV_LOG_FATAL,
1752 "Error: the video system does not support an image\n"
1753 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1754 "to reduce the image size.\n", vp->width, vp->height );
1758 SDL_LockMutex(is->pictq.mutex);
1760 SDL_CondSignal(is->pictq.cond);
1761 SDL_UnlockMutex(is->pictq.mutex);
1764 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1765 int i, width, height;
1767 for (i = 0; i < 3; i++) {
1774 if (bmp->pitches[i] > width) {
1775 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1776 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1782 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1786 #if defined(DEBUG_SYNC) && 0
1787 printf("frame_type=%c pts=%0.3f\n",
1788 av_get_picture_type_char(src_frame->pict_type), pts);
1791 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1794 vp->sar = src_frame->sample_aspect_ratio;
1796 /* alloc or resize hardware picture buffer */
1797 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1798 vp->width != src_frame->width ||
1799 vp->height != src_frame->height) {
1804 vp->width = src_frame->width;
1805 vp->height = src_frame->height;
1807 /* the allocation must be done in the main thread to avoid
1808 locking problems. */
1809 event.type = FF_ALLOC_EVENT;
1810 event.user.data1 = is;
1811 SDL_PushEvent(&event);
1813 /* wait until the picture is allocated */
1814 SDL_LockMutex(is->pictq.mutex);
1815 while (!vp->allocated && !is->videoq.abort_request) {
1816 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1818 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1819 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1820 while (!vp->allocated && !is->abort_request) {
1821 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1824 SDL_UnlockMutex(is->pictq.mutex);
1826 if (is->videoq.abort_request)
1830 /* if the frame is not skipped, then display it */
1832 AVPicture pict = { { 0 } };
1834 /* get a pointer on the bitmap */
1835 SDL_LockYUVOverlay (vp->bmp);
1837 pict.data[0] = vp->bmp->pixels[0];
1838 pict.data[1] = vp->bmp->pixels[2];
1839 pict.data[2] = vp->bmp->pixels[1];
1841 pict.linesize[0] = vp->bmp->pitches[0];
1842 pict.linesize[1] = vp->bmp->pitches[2];
1843 pict.linesize[2] = vp->bmp->pitches[1];
1846 // FIXME use direct rendering
1847 av_picture_copy(&pict, (AVPicture *)src_frame,
1848 src_frame->format, vp->width, vp->height);
1850 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1851 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1852 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1853 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1854 if (!is->img_convert_ctx) {
1855 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1858 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1859 0, vp->height, pict.data, pict.linesize);
1861 /* workaround SDL PITCH_WORKAROUND */
1862 duplicate_right_border_pixels(vp->bmp);
1863 /* update the bitmap content */
1864 SDL_UnlockYUVOverlay(vp->bmp);
1867 vp->duration = duration;
1869 vp->serial = serial;
1871 /* now we can update the picture count */
1872 frame_queue_push(&is->pictq);
1877 static int get_video_frame(VideoState *is, AVFrame *frame)
1881 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1887 if (frame->pts != AV_NOPTS_VALUE)
1888 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1890 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1892 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1893 if (frame->pts != AV_NOPTS_VALUE) {
1894 double diff = dpts - get_master_clock(is);
1895 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1896 diff - is->frame_last_filter_delay < 0 &&
1897 is->viddec.pkt_serial == is->vidclk.serial &&
1898 is->videoq.nb_packets) {
1899 is->frame_drops_early++;
1900 av_frame_unref(frame);
1911 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1912 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1915 int nb_filters = graph->nb_filters;
1916 AVFilterInOut *outputs = NULL, *inputs = NULL;
1919 outputs = avfilter_inout_alloc();
1920 inputs = avfilter_inout_alloc();
1921 if (!outputs || !inputs) {
1922 ret = AVERROR(ENOMEM);
1926 outputs->name = av_strdup("in");
1927 outputs->filter_ctx = source_ctx;
1928 outputs->pad_idx = 0;
1929 outputs->next = NULL;
1931 inputs->name = av_strdup("out");
1932 inputs->filter_ctx = sink_ctx;
1933 inputs->pad_idx = 0;
1934 inputs->next = NULL;
1936 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1939 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1943 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1944 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1945 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1947 ret = avfilter_graph_config(graph, NULL);
1949 avfilter_inout_free(&outputs);
1950 avfilter_inout_free(&inputs);
1954 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1956 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1957 char sws_flags_str[128];
1958 char buffersrc_args[256];
1960 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1961 AVCodecContext *codec = is->video_st->codec;
1962 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1964 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1965 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1966 graph->scale_sws_opts = av_strdup(sws_flags_str);
1968 snprintf(buffersrc_args, sizeof(buffersrc_args),
1969 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1970 frame->width, frame->height, frame->format,
1971 is->video_st->time_base.num, is->video_st->time_base.den,
1972 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1973 if (fr.num && fr.den)
1974 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1976 if ((ret = avfilter_graph_create_filter(&filt_src,
1977 avfilter_get_by_name("buffer"),
1978 "ffplay_buffer", buffersrc_args, NULL,
1982 ret = avfilter_graph_create_filter(&filt_out,
1983 avfilter_get_by_name("buffersink"),
1984 "ffplay_buffersink", NULL, NULL, graph);
1988 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1991 last_filter = filt_out;
1993 /* Note: this macro adds a filter before the lastly added filter, so the
1994 * processing order of the filters is in reverse */
1995 #define INSERT_FILT(name, arg) do { \
1996 AVFilterContext *filt_ctx; \
1998 ret = avfilter_graph_create_filter(&filt_ctx, \
1999 avfilter_get_by_name(name), \
2000 "ffplay_" name, arg, NULL, graph); \
2004 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
2008 last_filter = filt_ctx; \
2011 /* SDL YUV code is not handling odd width/height for some driver
2012 * combinations, therefore we crop the picture to an even width/height. */
2013 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
2016 AVDictionaryEntry *rotate_tag = av_dict_get(is->video_st->metadata, "rotate", NULL, 0);
2017 if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
2018 if (!strcmp(rotate_tag->value, "90")) {
2019 INSERT_FILT("transpose", "clock");
2020 } else if (!strcmp(rotate_tag->value, "180")) {
2021 INSERT_FILT("hflip", NULL);
2022 INSERT_FILT("vflip", NULL);
2023 } else if (!strcmp(rotate_tag->value, "270")) {
2024 INSERT_FILT("transpose", "cclock");
2026 char rotate_buf[64];
2027 snprintf(rotate_buf, sizeof(rotate_buf), "%s*PI/180", rotate_tag->value);
2028 INSERT_FILT("rotate", rotate_buf);
2033 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
2036 is->in_video_filter = filt_src;
2037 is->out_video_filter = filt_out;
2043 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
2045 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2046 int sample_rates[2] = { 0, -1 };
2047 int64_t channel_layouts[2] = { 0, -1 };
2048 int channels[2] = { 0, -1 };
2049 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2050 char aresample_swr_opts[512] = "";
2051 AVDictionaryEntry *e = NULL;
2052 char asrc_args[256];
2055 avfilter_graph_free(&is->agraph);
2056 if (!(is->agraph = avfilter_graph_alloc()))
2057 return AVERROR(ENOMEM);
2059 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2060 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2061 if (strlen(aresample_swr_opts))
2062 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2063 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2065 ret = snprintf(asrc_args, sizeof(asrc_args),
2066 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2067 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2068 is->audio_filter_src.channels,
2069 1, is->audio_filter_src.freq);
2070 if (is->audio_filter_src.channel_layout)
2071 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2072 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2074 ret = avfilter_graph_create_filter(&filt_asrc,
2075 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2076 asrc_args, NULL, is->agraph);
2081 ret = avfilter_graph_create_filter(&filt_asink,
2082 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2083 NULL, NULL, is->agraph);
2087 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2089 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2092 if (force_output_format) {
2093 channel_layouts[0] = is->audio_tgt.channel_layout;
2094 channels [0] = is->audio_tgt.channels;
2095 sample_rates [0] = is->audio_tgt.freq;
2096 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2098 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2100 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2102 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2107 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2110 is->in_audio_filter = filt_asrc;
2111 is->out_audio_filter = filt_asink;
2115 avfilter_graph_free(&is->agraph);
2118 #endif /* CONFIG_AVFILTER */
2120 static int audio_thread(void *arg)
2122 VideoState *is = arg;
2123 AVFrame *frame = av_frame_alloc();
2126 int last_serial = -1;
2127 int64_t dec_channel_layout;
2135 return AVERROR(ENOMEM);
2138 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2142 tb = (AVRational){1, frame->sample_rate};
2145 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2148 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2149 frame->format, av_frame_get_channels(frame)) ||
2150 is->audio_filter_src.channel_layout != dec_channel_layout ||
2151 is->audio_filter_src.freq != frame->sample_rate ||
2152 is->auddec.pkt_serial != last_serial;
2155 char buf1[1024], buf2[1024];
2156 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2157 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2158 av_log(NULL, AV_LOG_DEBUG,
2159 "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
2160 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2161 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2163 is->audio_filter_src.fmt = frame->format;
2164 is->audio_filter_src.channels = av_frame_get_channels(frame);
2165 is->audio_filter_src.channel_layout = dec_channel_layout;
2166 is->audio_filter_src.freq = frame->sample_rate;
2167 last_serial = is->auddec.pkt_serial;
2169 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2173 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2176 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2177 tb = is->out_audio_filter->inputs[0]->time_base;
2179 if (!(af = frame_queue_peek_writable(&is->sampq)))
2182 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2183 af->pos = av_frame_get_pkt_pos(frame);
2184 af->serial = is->auddec.pkt_serial;
2185 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2187 av_frame_move_ref(af->frame, frame);
2188 frame_queue_push(&is->sampq);
2191 if (is->audioq.serial != is->auddec.pkt_serial)
2194 if (ret == AVERROR_EOF)
2195 is->auddec.finished = is->auddec.pkt_serial;
2198 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2201 avfilter_graph_free(&is->agraph);
2203 av_frame_free(&frame);
2207 static void decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2209 packet_queue_start(d->queue);
2210 d->decoder_tid = SDL_CreateThread(fn, arg);
2213 static int video_thread(void *arg)
2215 VideoState *is = arg;
2216 AVFrame *frame = av_frame_alloc();
2220 AVRational tb = is->video_st->time_base;
2221 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2224 AVFilterGraph *graph = avfilter_graph_alloc();
2225 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2228 enum AVPixelFormat last_format = -2;
2229 int last_serial = -1;
2230 int last_vfilter_idx = 0;
2234 return AVERROR(ENOMEM);
2237 ret = get_video_frame(is, frame);
2244 if ( last_w != frame->width
2245 || last_h != frame->height
2246 || last_format != frame->format
2247 || last_serial != is->viddec.pkt_serial
2248 || last_vfilter_idx != is->vfilter_idx) {
2249 av_log(NULL, AV_LOG_DEBUG,
2250 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2252 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2253 frame->width, frame->height,
2254 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2255 avfilter_graph_free(&graph);
2256 graph = avfilter_graph_alloc();
2257 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2259 event.type = FF_QUIT_EVENT;
2260 event.user.data1 = is;
2261 SDL_PushEvent(&event);
2264 filt_in = is->in_video_filter;
2265 filt_out = is->out_video_filter;
2266 last_w = frame->width;
2267 last_h = frame->height;
2268 last_format = frame->format;
2269 last_serial = is->viddec.pkt_serial;
2270 last_vfilter_idx = is->vfilter_idx;
2271 frame_rate = filt_out->inputs[0]->frame_rate;
2274 ret = av_buffersrc_add_frame(filt_in, frame);
2279 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2281 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2283 if (ret == AVERROR_EOF)
2284 is->viddec.finished = is->viddec.pkt_serial;
2289 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2290 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2291 is->frame_last_filter_delay = 0;
2292 tb = filt_out->inputs[0]->time_base;
2294 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2295 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2296 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2297 av_frame_unref(frame);
2307 avfilter_graph_free(&graph);
2309 av_frame_free(&frame);
2313 static int subtitle_thread(void *arg)
2315 VideoState *is = arg;
2320 int r, g, b, y, u, v, a;
2323 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2326 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2331 if (got_subtitle && sp->sub.format == 0) {
2332 if (sp->sub.pts != AV_NOPTS_VALUE)
2333 pts = sp->sub.pts / (double)AV_TIME_BASE;
2335 sp->serial = is->subdec.pkt_serial;
2337 for (i = 0; i < sp->sub.num_rects; i++)
2339 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2341 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2342 y = RGB_TO_Y_CCIR(r, g, b);
2343 u = RGB_TO_U_CCIR(r, g, b, 0);
2344 v = RGB_TO_V_CCIR(r, g, b, 0);
2345 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2349 /* now we can update the picture count */
2350 frame_queue_push(&is->subpq);
2351 } else if (got_subtitle) {
2352 avsubtitle_free(&sp->sub);
2358 /* copy samples for viewing in editor window */
2359 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2363 size = samples_size / sizeof(short);
2365 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2368 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2370 is->sample_array_index += len;
2371 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2372 is->sample_array_index = 0;
2377 /* return the wanted number of samples to get better sync if sync_type is video
2378 * or external master clock */
2379 static int synchronize_audio(VideoState *is, int nb_samples)
2381 int wanted_nb_samples = nb_samples;
2383 /* if not master, then we try to remove or add samples to correct the clock */
2384 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2385 double diff, avg_diff;
2386 int min_nb_samples, max_nb_samples;
2388 diff = get_clock(&is->audclk) - get_master_clock(is);
2390 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2391 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2392 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2393 /* not enough measures to have a correct estimate */
2394 is->audio_diff_avg_count++;
2396 /* estimate the A-V difference */
2397 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2399 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2400 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2401 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2402 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2403 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2405 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2406 diff, avg_diff, wanted_nb_samples - nb_samples,
2407 is->audio_clock, is->audio_diff_threshold);
2410 /* too big difference : may be initial PTS errors, so
2412 is->audio_diff_avg_count = 0;
2413 is->audio_diff_cum = 0;
2417 return wanted_nb_samples;
2421 * Decode one audio frame and return its uncompressed size.
2423 * The processed audio frame is decoded, converted if required, and
2424 * stored in is->audio_buf, with size in bytes given by the return
2427 static int audio_decode_frame(VideoState *is)
2429 int data_size, resampled_data_size;
2430 int64_t dec_channel_layout;
2431 av_unused double audio_clock0;
2432 int wanted_nb_samples;
2439 if (!(af = frame_queue_peek_readable(&is->sampq)))
2441 frame_queue_next(&is->sampq);
2442 } while (af->serial != is->audioq.serial);
2444 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2445 af->frame->nb_samples,
2446 af->frame->format, 1);
2448 dec_channel_layout =
2449 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2450 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2451 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2453 if (af->frame->format != is->audio_src.fmt ||
2454 dec_channel_layout != is->audio_src.channel_layout ||
2455 af->frame->sample_rate != is->audio_src.freq ||
2456 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2457 swr_free(&is->swr_ctx);
2458 is->swr_ctx = swr_alloc_set_opts(NULL,
2459 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2460 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2462 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2463 av_log(NULL, AV_LOG_ERROR,
2464 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2465 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2466 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2467 swr_free(&is->swr_ctx);
2470 is->audio_src.channel_layout = dec_channel_layout;
2471 is->audio_src.channels = av_frame_get_channels(af->frame);
2472 is->audio_src.freq = af->frame->sample_rate;
2473 is->audio_src.fmt = af->frame->format;
2477 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2478 uint8_t **out = &is->audio_buf1;
2479 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2480 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2483 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2486 if (wanted_nb_samples != af->frame->nb_samples) {
2487 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2488 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2489 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2493 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2494 if (!is->audio_buf1)
2495 return AVERROR(ENOMEM);
2496 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2498 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2501 if (len2 == out_count) {
2502 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2503 if (swr_init(is->swr_ctx) < 0)
2504 swr_free(&is->swr_ctx);
2506 is->audio_buf = is->audio_buf1;
2507 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2509 is->audio_buf = af->frame->data[0];
2510 resampled_data_size = data_size;
2513 audio_clock0 = is->audio_clock;
2514 /* update the audio clock with the pts */
2515 if (!isnan(af->pts))
2516 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2518 is->audio_clock = NAN;
2519 is->audio_clock_serial = af->serial;
2522 static double last_clock;
2523 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2524 is->audio_clock - last_clock,
2525 is->audio_clock, audio_clock0);
2526 last_clock = is->audio_clock;
2529 return resampled_data_size;
2532 /* prepare a new audio buffer */
2533 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2535 VideoState *is = opaque;
2536 int audio_size, len1;
2538 audio_callback_time = av_gettime_relative();
2541 if (is->audio_buf_index >= is->audio_buf_size) {
2542 audio_size = audio_decode_frame(is);
2543 if (audio_size < 0) {
2544 /* if error, just output silence */
2545 is->audio_buf = is->silence_buf;
2546 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2548 if (is->show_mode != SHOW_MODE_VIDEO)
2549 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2550 is->audio_buf_size = audio_size;
2552 is->audio_buf_index = 0;
2554 len1 = is->audio_buf_size - is->audio_buf_index;
2557 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2560 is->audio_buf_index += len1;
2562 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2563 /* Let's assume the audio driver that is used by SDL has two periods. */
2564 if (!isnan(is->audio_clock)) {
2565 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);
2566 sync_clock_to_slave(&is->extclk, &is->audclk);
2570 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2572 SDL_AudioSpec wanted_spec, spec;
2574 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2575 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2576 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2578 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2580 wanted_nb_channels = atoi(env);
2581 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2583 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2584 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2585 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2587 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2588 wanted_spec.channels = wanted_nb_channels;
2589 wanted_spec.freq = wanted_sample_rate;
2590 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2591 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2594 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2595 next_sample_rate_idx--;
2596 wanted_spec.format = AUDIO_S16SYS;
2597 wanted_spec.silence = 0;
2598 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2599 wanted_spec.callback = sdl_audio_callback;
2600 wanted_spec.userdata = opaque;
2601 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2602 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2603 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2604 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2605 if (!wanted_spec.channels) {
2606 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2607 wanted_spec.channels = wanted_nb_channels;
2608 if (!wanted_spec.freq) {
2609 av_log(NULL, AV_LOG_ERROR,
2610 "No more combinations to try, audio open failed\n");
2614 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2616 if (spec.format != AUDIO_S16SYS) {
2617 av_log(NULL, AV_LOG_ERROR,
2618 "SDL advised audio format %d is not supported!\n", spec.format);
2621 if (spec.channels != wanted_spec.channels) {
2622 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2623 if (!wanted_channel_layout) {
2624 av_log(NULL, AV_LOG_ERROR,
2625 "SDL advised channel count %d is not supported!\n", spec.channels);
2630 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2631 audio_hw_params->freq = spec.freq;
2632 audio_hw_params->channel_layout = wanted_channel_layout;
2633 audio_hw_params->channels = spec.channels;
2634 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2635 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);
2636 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2637 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2643 /* open a given stream. Return 0 if OK */
2644 static int stream_component_open(VideoState *is, int stream_index)
2646 AVFormatContext *ic = is->ic;
2647 AVCodecContext *avctx;
2649 const char *forced_codec_name = NULL;
2651 AVDictionaryEntry *t = NULL;
2652 int sample_rate, nb_channels;
2653 int64_t channel_layout;
2655 int stream_lowres = lowres;
2657 if (stream_index < 0 || stream_index >= ic->nb_streams)
2659 avctx = ic->streams[stream_index]->codec;
2661 codec = avcodec_find_decoder(avctx->codec_id);
2663 switch(avctx->codec_type){
2664 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2665 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2666 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2668 if (forced_codec_name)
2669 codec = avcodec_find_decoder_by_name(forced_codec_name);
2671 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2672 "No codec could be found with name '%s'\n", forced_codec_name);
2673 else av_log(NULL, AV_LOG_WARNING,
2674 "No codec could be found with id %d\n", avctx->codec_id);
2678 avctx->codec_id = codec->id;
2679 if(stream_lowres > av_codec_get_max_lowres(codec)){
2680 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2681 av_codec_get_max_lowres(codec));
2682 stream_lowres = av_codec_get_max_lowres(codec);
2684 av_codec_set_lowres(avctx, stream_lowres);
2686 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2687 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2688 if(codec->capabilities & CODEC_CAP_DR1)
2689 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2691 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2692 if (!av_dict_get(opts, "threads", NULL, 0))
2693 av_dict_set(&opts, "threads", "auto", 0);
2695 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2696 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2697 av_dict_set(&opts, "refcounted_frames", "1", 0);
2698 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2701 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2702 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2703 ret = AVERROR_OPTION_NOT_FOUND;
2708 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2709 switch (avctx->codec_type) {
2710 case AVMEDIA_TYPE_AUDIO:
2715 is->audio_filter_src.freq = avctx->sample_rate;
2716 is->audio_filter_src.channels = avctx->channels;
2717 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2718 is->audio_filter_src.fmt = avctx->sample_fmt;
2719 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2721 link = is->out_audio_filter->inputs[0];
2722 sample_rate = link->sample_rate;
2723 nb_channels = link->channels;
2724 channel_layout = link->channel_layout;
2727 sample_rate = avctx->sample_rate;
2728 nb_channels = avctx->channels;
2729 channel_layout = avctx->channel_layout;
2732 /* prepare audio output */
2733 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2735 is->audio_hw_buf_size = ret;
2736 is->audio_src = is->audio_tgt;
2737 is->audio_buf_size = 0;
2738 is->audio_buf_index = 0;
2740 /* init averaging filter */
2741 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2742 is->audio_diff_avg_count = 0;
2743 /* since we do not have a precise anough audio fifo fullness,
2744 we correct audio sync only if larger than this threshold */
2745 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2747 is->audio_stream = stream_index;
2748 is->audio_st = ic->streams[stream_index];
2750 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2751 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2752 is->auddec.start_pts = is->audio_st->start_time;
2753 is->auddec.start_pts_tb = is->audio_st->time_base;
2755 decoder_start(&is->auddec, audio_thread, is);
2758 case AVMEDIA_TYPE_VIDEO:
2759 is->video_stream = stream_index;
2760 is->video_st = ic->streams[stream_index];
2762 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2763 decoder_start(&is->viddec, video_thread, is);
2764 is->queue_attachments_req = 1;
2766 case AVMEDIA_TYPE_SUBTITLE:
2767 is->subtitle_stream = stream_index;
2768 is->subtitle_st = ic->streams[stream_index];
2770 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2771 decoder_start(&is->subdec, subtitle_thread, is);
2778 av_dict_free(&opts);
2783 static void stream_component_close(VideoState *is, int stream_index)
2785 AVFormatContext *ic = is->ic;
2786 AVCodecContext *avctx;
2788 if (stream_index < 0 || stream_index >= ic->nb_streams)
2790 avctx = ic->streams[stream_index]->codec;
2792 switch (avctx->codec_type) {
2793 case AVMEDIA_TYPE_AUDIO:
2794 decoder_abort(&is->auddec, &is->sampq);
2796 decoder_destroy(&is->auddec);
2797 swr_free(&is->swr_ctx);
2798 av_freep(&is->audio_buf1);
2799 is->audio_buf1_size = 0;
2800 is->audio_buf = NULL;
2803 av_rdft_end(is->rdft);
2804 av_freep(&is->rdft_data);
2809 case AVMEDIA_TYPE_VIDEO:
2810 decoder_abort(&is->viddec, &is->pictq);
2811 decoder_destroy(&is->viddec);
2813 case AVMEDIA_TYPE_SUBTITLE:
2814 decoder_abort(&is->subdec, &is->subpq);
2815 decoder_destroy(&is->subdec);
2821 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2822 avcodec_close(avctx);
2823 switch (avctx->codec_type) {
2824 case AVMEDIA_TYPE_AUDIO:
2825 is->audio_st = NULL;
2826 is->audio_stream = -1;
2828 case AVMEDIA_TYPE_VIDEO:
2829 is->video_st = NULL;
2830 is->video_stream = -1;
2832 case AVMEDIA_TYPE_SUBTITLE:
2833 is->subtitle_st = NULL;
2834 is->subtitle_stream = -1;
2841 static int decode_interrupt_cb(void *ctx)
2843 VideoState *is = ctx;
2844 return is->abort_request;
2847 static int is_realtime(AVFormatContext *s)
2849 if( !strcmp(s->iformat->name, "rtp")
2850 || !strcmp(s->iformat->name, "rtsp")
2851 || !strcmp(s->iformat->name, "sdp")
2855 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2856 || !strncmp(s->filename, "udp:", 4)
2863 /* this thread gets the stream from the disk or the network */
2864 static int read_thread(void *arg)
2866 VideoState *is = arg;
2867 AVFormatContext *ic = NULL;
2869 int st_index[AVMEDIA_TYPE_NB];
2870 AVPacket pkt1, *pkt = &pkt1;
2871 int64_t stream_start_time;
2872 int pkt_in_play_range = 0;
2873 AVDictionaryEntry *t;
2874 AVDictionary **opts;
2875 int orig_nb_streams;
2876 SDL_mutex *wait_mutex = SDL_CreateMutex();
2877 int scan_all_pmts_set = 0;
2880 memset(st_index, -1, sizeof(st_index));
2881 is->last_video_stream = is->video_stream = -1;
2882 is->last_audio_stream = is->audio_stream = -1;
2883 is->last_subtitle_stream = is->subtitle_stream = -1;
2886 ic = avformat_alloc_context();
2888 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2889 ret = AVERROR(ENOMEM);
2892 ic->interrupt_callback.callback = decode_interrupt_cb;
2893 ic->interrupt_callback.opaque = is;
2894 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2895 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2896 scan_all_pmts_set = 1;
2898 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2900 print_error(is->filename, err);
2904 if (scan_all_pmts_set)
2905 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2907 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2908 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2909 ret = AVERROR_OPTION_NOT_FOUND;
2915 ic->flags |= AVFMT_FLAG_GENPTS;
2917 av_format_inject_global_side_data(ic);
2919 opts = setup_find_stream_info_opts(ic, codec_opts);
2920 orig_nb_streams = ic->nb_streams;
2922 err = avformat_find_stream_info(ic, opts);
2924 for (i = 0; i < orig_nb_streams; i++)
2925 av_dict_free(&opts[i]);
2929 av_log(NULL, AV_LOG_WARNING,
2930 "%s: could not find codec parameters\n", is->filename);
2936 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2938 if (seek_by_bytes < 0)
2939 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2941 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2943 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2944 window_title = av_asprintf("%s - %s", t->value, input_filename);
2946 /* if seeking requested, we execute it */
2947 if (start_time != AV_NOPTS_VALUE) {
2950 timestamp = start_time;
2951 /* add the stream start time */
2952 if (ic->start_time != AV_NOPTS_VALUE)
2953 timestamp += ic->start_time;
2954 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2956 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2957 is->filename, (double)timestamp / AV_TIME_BASE);
2961 is->realtime = is_realtime(ic);
2964 av_dump_format(ic, 0, is->filename, 0);
2966 for (i = 0; i < ic->nb_streams; i++) {
2967 AVStream *st = ic->streams[i];
2968 enum AVMediaType type = st->codec->codec_type;
2969 st->discard = AVDISCARD_ALL;
2970 if (wanted_stream_spec[type] && st_index[type] == -1)
2971 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2974 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2975 if (wanted_stream_spec[i] && st_index[i] == -1) {
2976 av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i));
2977 st_index[i] = INT_MAX;
2982 st_index[AVMEDIA_TYPE_VIDEO] =
2983 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2984 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2986 st_index[AVMEDIA_TYPE_AUDIO] =
2987 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2988 st_index[AVMEDIA_TYPE_AUDIO],
2989 st_index[AVMEDIA_TYPE_VIDEO],
2991 if (!video_disable && !subtitle_disable)
2992 st_index[AVMEDIA_TYPE_SUBTITLE] =
2993 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2994 st_index[AVMEDIA_TYPE_SUBTITLE],
2995 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2996 st_index[AVMEDIA_TYPE_AUDIO] :
2997 st_index[AVMEDIA_TYPE_VIDEO]),
3000 is->show_mode = show_mode;
3001 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3002 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
3003 AVCodecContext *avctx = st->codec;
3004 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
3006 set_default_window_size(avctx->width, avctx->height, sar);
3009 /* open the streams */
3010 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
3011 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
3015 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
3016 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
3018 if (is->show_mode == SHOW_MODE_NONE)
3019 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
3021 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
3022 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
3025 if (is->video_stream < 0 && is->audio_stream < 0) {
3026 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
3032 if (infinite_buffer < 0 && is->realtime)
3033 infinite_buffer = 1;
3036 if (is->abort_request)
3038 if (is->paused != is->last_paused) {
3039 is->last_paused = is->paused;
3041 is->read_pause_return = av_read_pause(ic);
3045 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3047 (!strcmp(ic->iformat->name, "rtsp") ||
3048 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3049 /* wait 10 ms to avoid trying to get another packet */
3056 int64_t seek_target = is->seek_pos;
3057 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3058 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3059 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3060 // of the seek_pos/seek_rel variables
3062 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3064 av_log(NULL, AV_LOG_ERROR,
3065 "%s: error while seeking\n", is->ic->filename);
3067 if (is->audio_stream >= 0) {
3068 packet_queue_flush(&is->audioq);
3069 packet_queue_put(&is->audioq, &flush_pkt);
3071 if (is->subtitle_stream >= 0) {
3072 packet_queue_flush(&is->subtitleq);
3073 packet_queue_put(&is->subtitleq, &flush_pkt);
3075 if (is->video_stream >= 0) {
3076 packet_queue_flush(&is->videoq);
3077 packet_queue_put(&is->videoq, &flush_pkt);
3079 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3080 set_clock(&is->extclk, NAN, 0);
3082 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3086 is->queue_attachments_req = 1;
3089 step_to_next_frame(is);
3091 if (is->queue_attachments_req) {
3092 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3094 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3096 packet_queue_put(&is->videoq, ©);
3097 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3099 is->queue_attachments_req = 0;
3102 /* if the queue are full, no need to read more */
3103 if (infinite_buffer<1 &&
3104 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3105 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3106 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3107 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3108 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3110 SDL_LockMutex(wait_mutex);
3111 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3112 SDL_UnlockMutex(wait_mutex);
3116 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3117 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3118 if (loop != 1 && (!loop || --loop)) {
3119 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3120 } else if (autoexit) {
3125 ret = av_read_frame(ic, pkt);
3127 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3128 if (is->video_stream >= 0)
3129 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3130 if (is->audio_stream >= 0)
3131 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3132 if (is->subtitle_stream >= 0)
3133 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3136 if (ic->pb && ic->pb->error)
3138 SDL_LockMutex(wait_mutex);
3139 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3140 SDL_UnlockMutex(wait_mutex);
3145 /* check if packet is in play range specified by user, then queue, otherwise discard */
3146 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3147 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3148 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3149 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3150 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3151 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3152 <= ((double)duration / 1000000);
3153 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3154 packet_queue_put(&is->audioq, pkt);
3155 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3156 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3157 packet_queue_put(&is->videoq, pkt);
3158 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3159 packet_queue_put(&is->subtitleq, pkt);
3161 av_free_packet(pkt);
3164 /* wait until the end */
3165 while (!is->abort_request) {
3171 /* close each stream */
3172 if (is->audio_stream >= 0)
3173 stream_component_close(is, is->audio_stream);
3174 if (is->video_stream >= 0)
3175 stream_component_close(is, is->video_stream);
3176 if (is->subtitle_stream >= 0)
3177 stream_component_close(is, is->subtitle_stream);
3179 avformat_close_input(&ic);
3186 event.type = FF_QUIT_EVENT;
3187 event.user.data1 = is;
3188 SDL_PushEvent(&event);
3190 SDL_DestroyMutex(wait_mutex);
3194 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3198 is = av_mallocz(sizeof(VideoState));
3201 av_strlcpy(is->filename, filename, sizeof(is->filename));
3202 is->iformat = iformat;
3206 /* start video display */
3207 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3209 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3211 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3214 packet_queue_init(&is->videoq);
3215 packet_queue_init(&is->audioq);
3216 packet_queue_init(&is->subtitleq);
3218 is->continue_read_thread = SDL_CreateCond();
3220 init_clock(&is->vidclk, &is->videoq.serial);
3221 init_clock(&is->audclk, &is->audioq.serial);
3222 init_clock(&is->extclk, &is->extclk.serial);
3223 is->audio_clock_serial = -1;
3224 is->av_sync_type = av_sync_type;
3225 is->read_tid = SDL_CreateThread(read_thread, is);
3226 if (!is->read_tid) {
3234 static void stream_cycle_channel(VideoState *is, int codec_type)
3236 AVFormatContext *ic = is->ic;
3237 int start_index, stream_index;
3240 AVProgram *p = NULL;
3241 int nb_streams = is->ic->nb_streams;
3243 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3244 start_index = is->last_video_stream;
3245 old_index = is->video_stream;
3246 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3247 start_index = is->last_audio_stream;
3248 old_index = is->audio_stream;
3250 start_index = is->last_subtitle_stream;
3251 old_index = is->subtitle_stream;
3253 stream_index = start_index;
3255 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3256 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3258 nb_streams = p->nb_stream_indexes;
3259 for (start_index = 0; start_index < nb_streams; start_index++)
3260 if (p->stream_index[start_index] == stream_index)
3262 if (start_index == nb_streams)
3264 stream_index = start_index;
3269 if (++stream_index >= nb_streams)
3271 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3274 is->last_subtitle_stream = -1;
3277 if (start_index == -1)
3281 if (stream_index == start_index)
3283 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3284 if (st->codec->codec_type == codec_type) {
3285 /* check that parameters are OK */
3286 switch (codec_type) {
3287 case AVMEDIA_TYPE_AUDIO:
3288 if (st->codec->sample_rate != 0 &&
3289 st->codec->channels != 0)
3292 case AVMEDIA_TYPE_VIDEO:
3293 case AVMEDIA_TYPE_SUBTITLE:
3301 if (p && stream_index != -1)
3302 stream_index = p->stream_index[stream_index];
3303 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3304 av_get_media_type_string(codec_type),
3308 stream_component_close(is, old_index);
3309 stream_component_open(is, stream_index);
3313 static void toggle_full_screen(VideoState *is)
3315 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3316 /* OS X needs to reallocate the SDL overlays */
3318 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3319 is->pictq.queue[i].reallocate = 1;
3321 is_full_screen = !is_full_screen;
3322 video_open(is, 1, NULL);
3325 static void toggle_audio_display(VideoState *is)
3327 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3328 int next = is->show_mode;
3330 next = (next + 1) % SHOW_MODE_NB;
3331 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3332 if (is->show_mode != next) {
3333 fill_rectangle(screen,
3334 is->xleft, is->ytop, is->width, is->height,
3336 is->force_refresh = 1;
3337 is->show_mode = next;
3341 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3342 double remaining_time = 0.0;
3344 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3345 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3349 if (remaining_time > 0.0)
3350 av_usleep((int64_t)(remaining_time * 1000000.0));
3351 remaining_time = REFRESH_RATE;
3352 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3353 video_refresh(is, &remaining_time);
3358 static void seek_chapter(VideoState *is, int incr)
3360 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3363 if (!is->ic->nb_chapters)
3366 /* find the current chapter */
3367 for (i = 0; i < is->ic->nb_chapters; i++) {
3368 AVChapter *ch = is->ic->chapters[i];
3369 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3377 if (i >= is->ic->nb_chapters)
3380 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3381 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3382 AV_TIME_BASE_Q), 0, 0);
3385 /* handle an event sent by the GUI */
3386 static void event_loop(VideoState *cur_stream)
3389 double incr, pos, frac;
3393 refresh_loop_wait_event(cur_stream, &event);
3394 switch (event.type) {
3396 if (exit_on_keydown) {
3397 do_exit(cur_stream);
3400 switch (event.key.keysym.sym) {
3403 do_exit(cur_stream);
3406 toggle_full_screen(cur_stream);
3407 cur_stream->force_refresh = 1;
3411 toggle_pause(cur_stream);
3413 case SDLK_s: // S: Step to next frame
3414 step_to_next_frame(cur_stream);
3417 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3420 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3423 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3424 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3425 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3428 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3432 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3433 if (++cur_stream->vfilter_idx >= nb_vfilters)
3434 cur_stream->vfilter_idx = 0;
3436 cur_stream->vfilter_idx = 0;
3437 toggle_audio_display(cur_stream);
3440 toggle_audio_display(cur_stream);
3444 if (cur_stream->ic->nb_chapters <= 1) {
3448 seek_chapter(cur_stream, 1);
3451 if (cur_stream->ic->nb_chapters <= 1) {
3455 seek_chapter(cur_stream, -1);
3469 if (seek_by_bytes) {
3471 if (pos < 0 && cur_stream->video_stream >= 0)
3472 pos = frame_queue_last_pos(&cur_stream->pictq);
3473 if (pos < 0 && cur_stream->audio_stream >= 0)
3474 pos = frame_queue_last_pos(&cur_stream->sampq);
3476 pos = avio_tell(cur_stream->ic->pb);
3477 if (cur_stream->ic->bit_rate)
3478 incr *= cur_stream->ic->bit_rate / 8.0;
3482 stream_seek(cur_stream, pos, incr, 1);
3484 pos = get_master_clock(cur_stream);
3486 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3488 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3489 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3490 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3497 case SDL_VIDEOEXPOSE:
3498 cur_stream->force_refresh = 1;
3500 case SDL_MOUSEBUTTONDOWN:
3501 if (exit_on_mousedown) {
3502 do_exit(cur_stream);
3505 case SDL_MOUSEMOTION:
3506 if (cursor_hidden) {
3510 cursor_last_shown = av_gettime_relative();
3511 if (event.type == SDL_MOUSEBUTTONDOWN) {
3514 if (event.motion.state != SDL_PRESSED)
3518 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3519 uint64_t size = avio_size(cur_stream->ic->pb);
3520 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3524 int tns, thh, tmm, tss;
3525 tns = cur_stream->ic->duration / 1000000LL;
3527 tmm = (tns % 3600) / 60;
3529 frac = x / cur_stream->width;
3532 mm = (ns % 3600) / 60;
3534 av_log(NULL, AV_LOG_INFO,
3535 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3536 hh, mm, ss, thh, tmm, tss);
3537 ts = frac * cur_stream->ic->duration;
3538 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3539 ts += cur_stream->ic->start_time;
3540 stream_seek(cur_stream, ts, 0, 0);
3543 case SDL_VIDEORESIZE:
3544 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3545 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3547 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3548 do_exit(cur_stream);
3550 screen_width = cur_stream->width = screen->w;
3551 screen_height = cur_stream->height = screen->h;
3552 cur_stream->force_refresh = 1;
3556 do_exit(cur_stream);
3558 case FF_ALLOC_EVENT:
3559 alloc_picture(event.user.data1);
3567 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3569 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3570 return opt_default(NULL, "video_size", arg);
3573 static int opt_width(void *optctx, const char *opt, const char *arg)
3575 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3579 static int opt_height(void *optctx, const char *opt, const char *arg)
3581 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3585 static int opt_format(void *optctx, const char *opt, const char *arg)
3587 file_iformat = av_find_input_format(arg);
3588 if (!file_iformat) {
3589 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3590 return AVERROR(EINVAL);
3595 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3597 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3598 return opt_default(NULL, "pixel_format", arg);
3601 static int opt_sync(void *optctx, const char *opt, const char *arg)
3603 if (!strcmp(arg, "audio"))
3604 av_sync_type = AV_SYNC_AUDIO_MASTER;
3605 else if (!strcmp(arg, "video"))
3606 av_sync_type = AV_SYNC_VIDEO_MASTER;
3607 else if (!strcmp(arg, "ext"))
3608 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3610 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3616 static int opt_seek(void *optctx, const char *opt, const char *arg)
3618 start_time = parse_time_or_die(opt, arg, 1);
3622 static int opt_duration(void *optctx, const char *opt, const char *arg)
3624 duration = parse_time_or_die(opt, arg, 1);
3628 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3630 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3631 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3632 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3633 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3637 static void opt_input_file(void *optctx, const char *filename)
3639 if (input_filename) {
3640 av_log(NULL, AV_LOG_FATAL,
3641 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3642 filename, input_filename);
3645 if (!strcmp(filename, "-"))
3647 input_filename = filename;
3650 static int opt_codec(void *optctx, const char *opt, const char *arg)
3652 const char *spec = strchr(opt, ':');
3654 av_log(NULL, AV_LOG_ERROR,
3655 "No media specifier was specified in '%s' in option '%s'\n",
3657 return AVERROR(EINVAL);
3661 case 'a' : audio_codec_name = arg; break;
3662 case 's' : subtitle_codec_name = arg; break;
3663 case 'v' : video_codec_name = arg; break;
3665 av_log(NULL, AV_LOG_ERROR,
3666 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3667 return AVERROR(EINVAL);
3674 static const OptionDef options[] = {
3675 #include "cmdutils_common_opts.h"
3676 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3677 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3678 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3679 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3680 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3681 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3682 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3683 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3684 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3685 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3686 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3687 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3688 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3689 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3690 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3691 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3692 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3693 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3694 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3695 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3696 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3697 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3698 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3699 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3700 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3701 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3702 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3703 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3704 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3706 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3707 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3709 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3710 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3711 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3712 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3713 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3714 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3715 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3716 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3717 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3721 static void show_usage(void)
3723 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3724 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3725 av_log(NULL, AV_LOG_INFO, "\n");
3728 void show_help_default(const char *opt, const char *arg)
3730 av_log_set_callback(log_callback_help);
3732 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3733 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3735 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3736 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3737 #if !CONFIG_AVFILTER
3738 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3740 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3742 printf("\nWhile playing:\n"
3744 "f toggle full screen\n"
3746 "a cycle audio channel in the current program\n"
3747 "v cycle video channel\n"
3748 "t cycle subtitle channel in the current program\n"
3750 "w cycle video filters or show modes\n"
3751 "s activate frame-step mode\n"
3752 "left/right seek backward/forward 10 seconds\n"
3753 "down/up seek backward/forward 1 minute\n"
3754 "page down/page up seek backward/forward 10 minutes\n"
3755 "mouse click seek to percentage in file corresponding to fraction of width\n"
3759 static int lockmgr(void **mtx, enum AVLockOp op)
3762 case AV_LOCK_CREATE:
3763 *mtx = SDL_CreateMutex();
3767 case AV_LOCK_OBTAIN:
3768 return !!SDL_LockMutex(*mtx);
3769 case AV_LOCK_RELEASE:
3770 return !!SDL_UnlockMutex(*mtx);
3771 case AV_LOCK_DESTROY:
3772 SDL_DestroyMutex(*mtx);
3778 /* Called from the main */
3779 int main(int argc, char **argv)
3783 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3785 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3786 parse_loglevel(argc, argv, options);
3788 /* register all codecs, demux and protocols */
3790 avdevice_register_all();
3793 avfilter_register_all();
3796 avformat_network_init();
3800 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3801 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3803 show_banner(argc, argv, options);
3805 parse_options(NULL, argc, argv, options, opt_input_file);
3807 if (!input_filename) {
3809 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3810 av_log(NULL, AV_LOG_FATAL,
3811 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3815 if (display_disable) {
3818 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3820 flags &= ~SDL_INIT_AUDIO;
3821 if (display_disable)
3822 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3823 #if !defined(_WIN32) && !defined(__APPLE__)
3824 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3826 if (SDL_Init (flags)) {
3827 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3828 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3832 if (!display_disable) {
3833 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3834 fs_screen_width = vi->current_w;
3835 fs_screen_height = vi->current_h;
3838 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3839 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3840 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3842 if (av_lockmgr_register(lockmgr)) {
3843 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3847 av_init_packet(&flush_pkt);
3848 flush_pkt.data = (uint8_t *)&flush_pkt;
3850 is = stream_open(input_filename, file_iformat);
3852 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");