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 FRAME_QUEUE_SIZE FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE)
126 typedef struct AudioParams {
129 int64_t channel_layout;
130 enum AVSampleFormat fmt;
135 typedef struct Clock {
136 double pts; /* clock base */
137 double pts_drift; /* clock base minus time at which we updated the clock */
140 int serial; /* clock is based on a packet with this serial */
142 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
145 /* Common struct for handling all types of decoded data and allocated render buffers. */
146 typedef struct Frame {
150 double pts; /* presentation timestamp for the frame */
151 double duration; /* estimated duration of the frame */
152 int64_t pos; /* byte position of the frame in the input file */
161 typedef struct FrameQueue {
162 Frame queue[FRAME_QUEUE_SIZE];
175 AV_SYNC_AUDIO_MASTER, /* default choice */
176 AV_SYNC_VIDEO_MASTER,
177 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
180 typedef struct Decoder {
184 AVCodecContext *avctx;
189 SDL_cond *empty_queue_cond;
191 AVRational start_pts_tb;
193 AVRational next_pts_tb;
196 typedef struct VideoState {
197 SDL_Thread *read_tid;
198 SDL_Thread *video_tid;
199 AVInputFormat *iformat;
205 int queue_attachments_req;
210 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 int audio_buf_frames_pending;
246 int audio_last_serial;
247 struct AudioParams audio_src;
249 struct AudioParams audio_filter_src;
251 struct AudioParams audio_tgt;
252 struct SwrContext *swr_ctx;
253 int frame_drops_early;
254 int frame_drops_late;
258 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
260 int16_t sample_array[SAMPLE_ARRAY_SIZE];
261 int sample_array_index;
265 FFTSample *rdft_data;
267 double last_vis_time;
269 SDL_Thread *subtitle_tid;
271 AVStream *subtitle_st;
272 PacketQueue subtitleq;
275 double frame_last_returned_time;
276 double frame_last_filter_delay;
280 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
282 struct SwsContext *img_convert_ctx;
284 SDL_Rect last_display_rect;
287 int width, height, xleft, ytop;
292 AVFilterContext *in_video_filter; // the first filter in the video chain
293 AVFilterContext *out_video_filter; // the last filter in the video chain
294 AVFilterContext *in_audio_filter; // the first filter in the audio chain
295 AVFilterContext *out_audio_filter; // the last filter in the audio chain
296 AVFilterGraph *agraph; // audio filter graph
299 int last_video_stream, last_audio_stream, last_subtitle_stream;
301 SDL_cond *continue_read_thread;
304 /* options specified by the user */
305 static AVInputFormat *file_iformat;
306 static const char *input_filename;
307 static const char *window_title;
308 static int fs_screen_width;
309 static int fs_screen_height;
310 static int default_width = 640;
311 static int default_height = 480;
312 static int screen_width = 0;
313 static int screen_height = 0;
314 static int audio_disable;
315 static int video_disable;
316 static int subtitle_disable;
317 static int wanted_stream[AVMEDIA_TYPE_NB] = {
318 [AVMEDIA_TYPE_AUDIO] = -1,
319 [AVMEDIA_TYPE_VIDEO] = -1,
320 [AVMEDIA_TYPE_SUBTITLE] = -1,
322 static int seek_by_bytes = -1;
323 static int display_disable;
324 static int show_status = 1;
325 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
326 static int64_t start_time = AV_NOPTS_VALUE;
327 static int64_t duration = AV_NOPTS_VALUE;
329 static int genpts = 0;
330 static int lowres = 0;
331 static int decoder_reorder_pts = -1;
333 static int exit_on_keydown;
334 static int exit_on_mousedown;
336 static int framedrop = -1;
337 static int infinite_buffer = -1;
338 static enum ShowMode show_mode = SHOW_MODE_NONE;
339 static const char *audio_codec_name;
340 static const char *subtitle_codec_name;
341 static const char *video_codec_name;
342 double rdftspeed = 0.02;
343 static int64_t cursor_last_shown;
344 static int cursor_hidden = 0;
346 static const char **vfilters_list = NULL;
347 static int nb_vfilters = 0;
348 static char *afilters = NULL;
350 static int autorotate = 1;
352 /* current context */
353 static int is_full_screen;
354 static int64_t audio_callback_time;
356 static AVPacket flush_pkt;
358 #define FF_ALLOC_EVENT (SDL_USEREVENT)
359 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
361 static SDL_Surface *screen;
364 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
366 GROW_ARRAY(vfilters_list, nb_vfilters);
367 vfilters_list[nb_vfilters - 1] = arg;
373 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
374 enum AVSampleFormat fmt2, int64_t channel_count2)
376 /* If channel count == 1, planar and non-planar formats are the same */
377 if (channel_count1 == 1 && channel_count2 == 1)
378 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
380 return channel_count1 != channel_count2 || fmt1 != fmt2;
384 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
386 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
387 return channel_layout;
392 static void free_picture(Frame *vp);
394 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
396 MyAVPacketList *pkt1;
398 if (q->abort_request)
401 pkt1 = av_malloc(sizeof(MyAVPacketList));
406 if (pkt == &flush_pkt)
408 pkt1->serial = q->serial;
413 q->last_pkt->next = pkt1;
416 q->size += pkt1->pkt.size + sizeof(*pkt1);
417 /* XXX: should duplicate packet data in DV case */
418 SDL_CondSignal(q->cond);
422 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
426 /* duplicate the packet */
427 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
430 SDL_LockMutex(q->mutex);
431 ret = packet_queue_put_private(q, pkt);
432 SDL_UnlockMutex(q->mutex);
434 if (pkt != &flush_pkt && ret < 0)
440 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
442 AVPacket pkt1, *pkt = &pkt1;
446 pkt->stream_index = stream_index;
447 return packet_queue_put(q, pkt);
450 /* packet queue handling */
451 static void packet_queue_init(PacketQueue *q)
453 memset(q, 0, sizeof(PacketQueue));
454 q->mutex = SDL_CreateMutex();
455 q->cond = SDL_CreateCond();
456 q->abort_request = 1;
459 static void packet_queue_flush(PacketQueue *q)
461 MyAVPacketList *pkt, *pkt1;
463 SDL_LockMutex(q->mutex);
464 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
466 av_free_packet(&pkt->pkt);
473 SDL_UnlockMutex(q->mutex);
476 static void packet_queue_destroy(PacketQueue *q)
478 packet_queue_flush(q);
479 SDL_DestroyMutex(q->mutex);
480 SDL_DestroyCond(q->cond);
483 static void packet_queue_abort(PacketQueue *q)
485 SDL_LockMutex(q->mutex);
487 q->abort_request = 1;
489 SDL_CondSignal(q->cond);
491 SDL_UnlockMutex(q->mutex);
494 static void packet_queue_start(PacketQueue *q)
496 SDL_LockMutex(q->mutex);
497 q->abort_request = 0;
498 packet_queue_put_private(q, &flush_pkt);
499 SDL_UnlockMutex(q->mutex);
502 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
503 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
505 MyAVPacketList *pkt1;
508 SDL_LockMutex(q->mutex);
511 if (q->abort_request) {
518 q->first_pkt = pkt1->next;
522 q->size -= pkt1->pkt.size + sizeof(*pkt1);
525 *serial = pkt1->serial;
533 SDL_CondWait(q->cond, q->mutex);
536 SDL_UnlockMutex(q->mutex);
540 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
541 memset(d, 0, sizeof(Decoder));
544 d->empty_queue_cond = empty_queue_cond;
545 d->start_pts = AV_NOPTS_VALUE;
548 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
556 if (d->queue->abort_request)
559 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
562 if (d->queue->nb_packets == 0)
563 SDL_CondSignal(d->empty_queue_cond);
564 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
566 if (pkt.data == flush_pkt.data) {
567 avcodec_flush_buffers(d->avctx);
570 d->next_pts = d->start_pts;
571 d->next_pts_tb = d->start_pts_tb;
573 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
574 av_free_packet(&d->pkt);
575 d->pkt_temp = d->pkt = pkt;
576 d->packet_pending = 1;
579 switch (d->avctx->codec_type) {
580 case AVMEDIA_TYPE_VIDEO:
581 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
583 if (decoder_reorder_pts == -1) {
584 frame->pts = av_frame_get_best_effort_timestamp(frame);
585 } else if (decoder_reorder_pts) {
586 frame->pts = frame->pkt_pts;
588 frame->pts = frame->pkt_dts;
592 case AVMEDIA_TYPE_AUDIO:
593 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
595 AVRational tb = (AVRational){1, frame->sample_rate};
596 if (frame->pts != AV_NOPTS_VALUE)
597 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
598 else if (frame->pkt_pts != AV_NOPTS_VALUE)
599 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
600 else if (d->next_pts != AV_NOPTS_VALUE)
601 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
602 if (frame->pts != AV_NOPTS_VALUE) {
603 d->next_pts = frame->pts + frame->nb_samples;
608 case AVMEDIA_TYPE_SUBTITLE:
609 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
614 d->packet_pending = 0;
617 d->pkt_temp.pts = AV_NOPTS_VALUE;
618 if (d->pkt_temp.data) {
619 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
620 ret = d->pkt_temp.size;
621 d->pkt_temp.data += ret;
622 d->pkt_temp.size -= ret;
623 if (d->pkt_temp.size <= 0)
624 d->packet_pending = 0;
627 d->packet_pending = 0;
628 d->finished = d->pkt_serial;
632 } while (!got_frame && !d->finished);
637 static void decoder_destroy(Decoder *d) {
638 av_free_packet(&d->pkt);
641 static void frame_queue_unref_item(Frame *vp)
643 av_frame_unref(vp->frame);
644 avsubtitle_free(&vp->sub);
647 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
650 memset(f, 0, sizeof(FrameQueue));
651 if (!(f->mutex = SDL_CreateMutex()))
652 return AVERROR(ENOMEM);
653 if (!(f->cond = SDL_CreateCond()))
654 return AVERROR(ENOMEM);
656 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
657 f->keep_last = !!keep_last;
658 for (i = 0; i < f->max_size; i++)
659 if (!(f->queue[i].frame = av_frame_alloc()))
660 return AVERROR(ENOMEM);
664 static void frame_queue_destory(FrameQueue *f)
667 for (i = 0; i < f->max_size; i++) {
668 Frame *vp = &f->queue[i];
669 frame_queue_unref_item(vp);
670 av_frame_free(&vp->frame);
673 SDL_DestroyMutex(f->mutex);
674 SDL_DestroyCond(f->cond);
677 static void frame_queue_signal(FrameQueue *f)
679 SDL_LockMutex(f->mutex);
680 SDL_CondSignal(f->cond);
681 SDL_UnlockMutex(f->mutex);
684 static Frame *frame_queue_peek(FrameQueue *f)
686 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
689 static Frame *frame_queue_peek_next(FrameQueue *f)
691 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
694 static Frame *frame_queue_peek_last(FrameQueue *f)
696 return &f->queue[f->rindex];
699 static Frame *frame_queue_peek_writable(FrameQueue *f)
701 /* wait until we have space to put a new frame */
702 SDL_LockMutex(f->mutex);
703 while (f->size >= f->max_size &&
704 !f->pktq->abort_request) {
705 SDL_CondWait(f->cond, f->mutex);
707 SDL_UnlockMutex(f->mutex);
709 if (f->pktq->abort_request)
712 return &f->queue[f->windex];
715 static void frame_queue_push(FrameQueue *f)
717 if (++f->windex == f->max_size)
719 SDL_LockMutex(f->mutex);
721 SDL_UnlockMutex(f->mutex);
724 static void frame_queue_next(FrameQueue *f)
726 if (f->keep_last && !f->rindex_shown) {
730 frame_queue_unref_item(&f->queue[f->rindex]);
731 if (++f->rindex == f->max_size)
733 SDL_LockMutex(f->mutex);
735 SDL_CondSignal(f->cond);
736 SDL_UnlockMutex(f->mutex);
739 /* jump back to the previous frame if available by resetting rindex_shown */
740 static int frame_queue_prev(FrameQueue *f)
742 int ret = f->rindex_shown;
747 /* return the number of undisplayed frames in the queue */
748 static int frame_queue_nb_remaining(FrameQueue *f)
750 return f->size - f->rindex_shown;
753 /* return last shown position */
754 static int64_t frame_queue_last_pos(FrameQueue *f)
756 Frame *fp = &f->queue[f->rindex];
757 if (f->rindex_shown && fp->serial == f->pktq->serial)
763 static inline void fill_rectangle(SDL_Surface *screen,
764 int x, int y, int w, int h, int color, int update)
771 SDL_FillRect(screen, &rect, color);
772 if (update && w > 0 && h > 0)
773 SDL_UpdateRect(screen, x, y, w, h);
776 /* draw only the border of a rectangle */
777 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
781 /* fill the background */
785 w2 = width - (x + w);
791 h2 = height - (y + h);
794 fill_rectangle(screen,
798 fill_rectangle(screen,
799 xleft + width - w2, ytop,
802 fill_rectangle(screen,
806 fill_rectangle(screen,
807 xleft + w1, ytop + height - h2,
812 #define ALPHA_BLEND(a, oldp, newp, s)\
813 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
815 #define RGBA_IN(r, g, b, a, s)\
817 unsigned int v = ((const uint32_t *)(s))[0];\
818 a = (v >> 24) & 0xff;\
819 r = (v >> 16) & 0xff;\
820 g = (v >> 8) & 0xff;\
824 #define YUVA_IN(y, u, v, a, s, pal)\
826 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
827 a = (val >> 24) & 0xff;\
828 y = (val >> 16) & 0xff;\
829 u = (val >> 8) & 0xff;\
833 #define YUVA_OUT(d, y, u, v, a)\
835 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
841 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
843 int wrap, wrap3, width2, skip2;
844 int y, u, v, a, u1, v1, a1, w, h;
845 uint8_t *lum, *cb, *cr;
848 int dstx, dsty, dstw, dsth;
850 dstw = av_clip(rect->w, 0, imgw);
851 dsth = av_clip(rect->h, 0, imgh);
852 dstx = av_clip(rect->x, 0, imgw - dstw);
853 dsty = av_clip(rect->y, 0, imgh - dsth);
854 lum = dst->data[0] + dsty * dst->linesize[0];
855 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
856 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
858 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
860 wrap = dst->linesize[0];
861 wrap3 = rect->pict.linesize[0];
862 p = rect->pict.data[0];
863 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
871 YUVA_IN(y, u, v, a, p, pal);
872 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
873 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
874 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
880 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
881 YUVA_IN(y, u, v, a, p, pal);
885 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
887 YUVA_IN(y, u, v, a, p + BPP, pal);
891 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
892 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
893 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
900 YUVA_IN(y, u, v, a, p, pal);
901 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
902 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
903 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
907 p += wrap3 - dstw * BPP;
908 lum += wrap - dstw - dstx;
909 cb += dst->linesize[1] - width2 - skip2;
910 cr += dst->linesize[2] - width2 - skip2;
912 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
918 YUVA_IN(y, u, v, a, p, pal);
922 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
925 YUVA_IN(y, u, v, a, p, pal);
929 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
930 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
931 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
937 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
938 YUVA_IN(y, u, v, a, p, pal);
942 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
944 YUVA_IN(y, u, v, a, p + BPP, pal);
948 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
952 YUVA_IN(y, u, v, a, p, pal);
956 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
958 YUVA_IN(y, u, v, a, p + BPP, pal);
962 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
964 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
965 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
969 p += -wrap3 + 2 * BPP;
973 YUVA_IN(y, u, v, a, p, pal);
977 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
980 YUVA_IN(y, u, v, a, p, pal);
984 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
985 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
986 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
992 p += wrap3 + (wrap3 - dstw * BPP);
993 lum += wrap + (wrap - dstw - dstx);
994 cb += dst->linesize[1] - width2 - skip2;
995 cr += dst->linesize[2] - width2 - skip2;
997 /* handle odd height */
1004 YUVA_IN(y, u, v, a, p, pal);
1005 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1006 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1007 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1013 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
1014 YUVA_IN(y, u, v, a, p, pal);
1018 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1020 YUVA_IN(y, u, v, a, p + BPP, pal);
1024 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
1025 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
1026 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
1033 YUVA_IN(y, u, v, a, p, pal);
1034 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1035 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1036 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1041 static void free_picture(Frame *vp)
1044 SDL_FreeYUVOverlay(vp->bmp);
1049 static void calculate_display_rect(SDL_Rect *rect,
1050 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
1051 int pic_width, int pic_height, AVRational pic_sar)
1054 int width, height, x, y;
1056 if (pic_sar.num == 0)
1059 aspect_ratio = av_q2d(pic_sar);
1061 if (aspect_ratio <= 0.0)
1063 aspect_ratio *= (float)pic_width / (float)pic_height;
1065 /* XXX: we suppose the screen has a 1.0 pixel ratio */
1066 height = scr_height;
1067 width = ((int)rint(height * aspect_ratio)) & ~1;
1068 if (width > scr_width) {
1070 height = ((int)rint(width / aspect_ratio)) & ~1;
1072 x = (scr_width - width) / 2;
1073 y = (scr_height - height) / 2;
1074 rect->x = scr_xleft + x;
1075 rect->y = scr_ytop + y;
1076 rect->w = FFMAX(width, 1);
1077 rect->h = FFMAX(height, 1);
1080 static void video_image_display(VideoState *is)
1088 vp = frame_queue_peek(&is->pictq);
1090 if (is->subtitle_st) {
1091 if (frame_queue_nb_remaining(&is->subpq) > 0) {
1092 sp = frame_queue_peek(&is->subpq);
1094 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
1095 SDL_LockYUVOverlay (vp->bmp);
1097 pict.data[0] = vp->bmp->pixels[0];
1098 pict.data[1] = vp->bmp->pixels[2];
1099 pict.data[2] = vp->bmp->pixels[1];
1101 pict.linesize[0] = vp->bmp->pitches[0];
1102 pict.linesize[1] = vp->bmp->pitches[2];
1103 pict.linesize[2] = vp->bmp->pitches[1];
1105 for (i = 0; i < sp->sub.num_rects; i++)
1106 blend_subrect(&pict, sp->sub.rects[i],
1107 vp->bmp->w, vp->bmp->h);
1109 SDL_UnlockYUVOverlay (vp->bmp);
1114 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1116 SDL_DisplayYUVOverlay(vp->bmp, &rect);
1118 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) {
1119 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1120 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
1121 is->last_display_rect = rect;
1126 static inline int compute_mod(int a, int b)
1128 return a < 0 ? a%b + b : a%b;
1131 static void video_audio_display(VideoState *s)
1133 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1134 int ch, channels, h, h2, bgcolor, fgcolor;
1136 int rdft_bits, nb_freq;
1138 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1140 nb_freq = 1 << (rdft_bits - 1);
1142 /* compute display index : center on currently output samples */
1143 channels = s->audio_tgt.channels;
1144 nb_display_channels = channels;
1146 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1148 delay = s->audio_write_buf_size;
1151 /* to be more precise, we take into account the time spent since
1152 the last buffer computation */
1153 if (audio_callback_time) {
1154 time_diff = av_gettime_relative() - audio_callback_time;
1155 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1158 delay += 2 * data_used;
1159 if (delay < data_used)
1162 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1163 if (s->show_mode == SHOW_MODE_WAVES) {
1165 for (i = 0; i < 1000; i += channels) {
1166 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1167 int a = s->sample_array[idx];
1168 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1169 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1170 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1172 if (h < score && (b ^ c) < 0) {
1179 s->last_i_start = i_start;
1181 i_start = s->last_i_start;
1184 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1185 if (s->show_mode == SHOW_MODE_WAVES) {
1186 fill_rectangle(screen,
1187 s->xleft, s->ytop, s->width, s->height,
1190 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1192 /* total height for one channel */
1193 h = s->height / nb_display_channels;
1194 /* graph height / 2 */
1196 for (ch = 0; ch < nb_display_channels; ch++) {
1198 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1199 for (x = 0; x < s->width; x++) {
1200 y = (s->sample_array[i] * h2) >> 15;
1207 fill_rectangle(screen,
1208 s->xleft + x, ys, 1, y,
1211 if (i >= SAMPLE_ARRAY_SIZE)
1212 i -= SAMPLE_ARRAY_SIZE;
1216 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1218 for (ch = 1; ch < nb_display_channels; ch++) {
1219 y = s->ytop + ch * h;
1220 fill_rectangle(screen,
1221 s->xleft, y, s->width, 1,
1224 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1226 nb_display_channels= FFMIN(nb_display_channels, 2);
1227 if (rdft_bits != s->rdft_bits) {
1228 av_rdft_end(s->rdft);
1229 av_free(s->rdft_data);
1230 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1231 s->rdft_bits = rdft_bits;
1232 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1236 for (ch = 0; ch < nb_display_channels; ch++) {
1237 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1239 for (x = 0; x < 2 * nb_freq; x++) {
1240 double w = (x-nb_freq) * (1.0 / nb_freq);
1241 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1243 if (i >= SAMPLE_ARRAY_SIZE)
1244 i -= SAMPLE_ARRAY_SIZE;
1246 av_rdft_calc(s->rdft, data[ch]);
1248 /* Least efficient way to do this, we should of course
1249 * directly access it but it is more than fast enough. */
1250 for (y = 0; y < s->height; y++) {
1251 double w = 1 / sqrt(nb_freq);
1252 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]));
1253 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1254 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1257 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1259 fill_rectangle(screen,
1260 s->xpos, s->height-y, 1, 1,
1264 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1267 if (s->xpos >= s->width)
1272 static void stream_close(VideoState *is)
1274 /* XXX: use a special url_shutdown call to abort parse cleanly */
1275 is->abort_request = 1;
1276 SDL_WaitThread(is->read_tid, NULL);
1277 packet_queue_destroy(&is->videoq);
1278 packet_queue_destroy(&is->audioq);
1279 packet_queue_destroy(&is->subtitleq);
1281 /* free all pictures */
1282 frame_queue_destory(&is->pictq);
1283 frame_queue_destory(&is->subpq);
1284 SDL_DestroyCond(is->continue_read_thread);
1285 #if !CONFIG_AVFILTER
1286 sws_freeContext(is->img_convert_ctx);
1291 static void do_exit(VideoState *is)
1296 av_lockmgr_register(NULL);
1299 av_freep(&vfilters_list);
1301 avformat_network_deinit();
1305 av_log(NULL, AV_LOG_QUIET, "%s", "");
1309 static void sigterm_handler(int sig)
1314 static void set_default_window_size(int width, int height, AVRational sar)
1317 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1318 default_width = rect.w;
1319 default_height = rect.h;
1322 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1324 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1327 if (is_full_screen) flags |= SDL_FULLSCREEN;
1328 else flags |= SDL_RESIZABLE;
1330 if (vp && vp->width)
1331 set_default_window_size(vp->width, vp->height, vp->sar);
1333 if (is_full_screen && fs_screen_width) {
1334 w = fs_screen_width;
1335 h = fs_screen_height;
1336 } else if (!is_full_screen && screen_width) {
1343 w = FFMIN(16383, w);
1344 if (screen && is->width == screen->w && screen->w == w
1345 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1347 screen = SDL_SetVideoMode(w, h, 0, flags);
1349 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1353 window_title = input_filename;
1354 SDL_WM_SetCaption(window_title, window_title);
1356 is->width = screen->w;
1357 is->height = screen->h;
1362 /* display the current picture, if any */
1363 static void video_display(VideoState *is)
1366 video_open(is, 0, NULL);
1367 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1368 video_audio_display(is);
1369 else if (is->video_st)
1370 video_image_display(is);
1373 static double get_clock(Clock *c)
1375 if (*c->queue_serial != c->serial)
1380 double time = av_gettime_relative() / 1000000.0;
1381 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1385 static void set_clock_at(Clock *c, double pts, int serial, double time)
1388 c->last_updated = time;
1389 c->pts_drift = c->pts - time;
1393 static void set_clock(Clock *c, double pts, int serial)
1395 double time = av_gettime_relative() / 1000000.0;
1396 set_clock_at(c, pts, serial, time);
1399 static void set_clock_speed(Clock *c, double speed)
1401 set_clock(c, get_clock(c), c->serial);
1405 static void init_clock(Clock *c, int *queue_serial)
1409 c->queue_serial = queue_serial;
1410 set_clock(c, NAN, -1);
1413 static void sync_clock_to_slave(Clock *c, Clock *slave)
1415 double clock = get_clock(c);
1416 double slave_clock = get_clock(slave);
1417 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1418 set_clock(c, slave_clock, slave->serial);
1421 static int get_master_sync_type(VideoState *is) {
1422 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1424 return AV_SYNC_VIDEO_MASTER;
1426 return AV_SYNC_AUDIO_MASTER;
1427 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1429 return AV_SYNC_AUDIO_MASTER;
1431 return AV_SYNC_EXTERNAL_CLOCK;
1433 return AV_SYNC_EXTERNAL_CLOCK;
1437 /* get the current master clock value */
1438 static double get_master_clock(VideoState *is)
1442 switch (get_master_sync_type(is)) {
1443 case AV_SYNC_VIDEO_MASTER:
1444 val = get_clock(&is->vidclk);
1446 case AV_SYNC_AUDIO_MASTER:
1447 val = get_clock(&is->audclk);
1450 val = get_clock(&is->extclk);
1456 static void check_external_clock_speed(VideoState *is) {
1457 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1458 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1459 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1460 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1461 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1462 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1464 double speed = is->extclk.speed;
1466 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1470 /* seek in the stream */
1471 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1473 if (!is->seek_req) {
1476 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1478 is->seek_flags |= AVSEEK_FLAG_BYTE;
1480 SDL_CondSignal(is->continue_read_thread);
1484 /* pause or resume the video */
1485 static void stream_toggle_pause(VideoState *is)
1488 is->frame_timer += av_gettime_relative() / 1000000.0 + is->vidclk.pts_drift - is->vidclk.pts;
1489 if (is->read_pause_return != AVERROR(ENOSYS)) {
1490 is->vidclk.paused = 0;
1492 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1494 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1495 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1498 static void toggle_pause(VideoState *is)
1500 stream_toggle_pause(is);
1504 static void step_to_next_frame(VideoState *is)
1506 /* if the stream is paused unpause it, then step */
1508 stream_toggle_pause(is);
1512 static double compute_target_delay(double delay, VideoState *is)
1514 double sync_threshold, diff;
1516 /* update delay to follow master synchronisation source */
1517 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1518 /* if video is slave, we try to correct big delays by
1519 duplicating or deleting a frame */
1520 diff = get_clock(&is->vidclk) - get_master_clock(is);
1522 /* skip or repeat frame. We take into account the
1523 delay to compute the threshold. I still don't know
1524 if it is the best guess */
1525 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1526 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1527 if (diff <= -sync_threshold)
1528 delay = FFMAX(0, delay + diff);
1529 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1530 delay = delay + diff;
1531 else if (diff >= sync_threshold)
1536 av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1542 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1543 if (vp->serial == nextvp->serial) {
1544 double duration = nextvp->pts - vp->pts;
1545 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1546 return vp->duration;
1554 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1555 /* update current video pts */
1556 set_clock(&is->vidclk, pts, serial);
1557 sync_clock_to_slave(&is->extclk, &is->vidclk);
1560 /* called to display each frame */
1561 static void video_refresh(void *opaque, double *remaining_time)
1563 VideoState *is = opaque;
1568 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1569 check_external_clock_speed(is);
1571 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1572 time = av_gettime_relative() / 1000000.0;
1573 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1575 is->last_vis_time = time;
1577 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1582 if (is->force_refresh)
1583 redisplay = frame_queue_prev(&is->pictq);
1585 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1586 // nothing to do, no picture to display in the queue
1588 double last_duration, duration, delay;
1591 /* dequeue the picture */
1592 lastvp = frame_queue_peek_last(&is->pictq);
1593 vp = frame_queue_peek(&is->pictq);
1595 if (vp->serial != is->videoq.serial) {
1596 frame_queue_next(&is->pictq);
1601 if (lastvp->serial != vp->serial && !redisplay)
1602 is->frame_timer = av_gettime_relative() / 1000000.0;
1607 /* compute nominal last_duration */
1608 last_duration = vp_duration(is, lastvp, vp);
1612 delay = compute_target_delay(last_duration, is);
1614 time= av_gettime_relative()/1000000.0;
1615 if (time < is->frame_timer + delay && !redisplay) {
1616 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1620 is->frame_timer += delay;
1621 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1622 is->frame_timer = time;
1624 SDL_LockMutex(is->pictq.mutex);
1625 if (!redisplay && !isnan(vp->pts))
1626 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1627 SDL_UnlockMutex(is->pictq.mutex);
1629 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1630 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1631 duration = vp_duration(is, vp, nextvp);
1632 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1634 is->frame_drops_late++;
1635 frame_queue_next(&is->pictq);
1641 if (is->subtitle_st) {
1642 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1643 sp = frame_queue_peek(&is->subpq);
1645 if (frame_queue_nb_remaining(&is->subpq) > 1)
1646 sp2 = frame_queue_peek_next(&is->subpq);
1650 if (sp->serial != is->subtitleq.serial
1651 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1652 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1654 frame_queue_next(&is->subpq);
1662 /* display picture */
1663 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1666 frame_queue_next(&is->pictq);
1668 if (is->step && !is->paused)
1669 stream_toggle_pause(is);
1672 is->force_refresh = 0;
1674 static int64_t last_time;
1676 int aqsize, vqsize, sqsize;
1679 cur_time = av_gettime_relative();
1680 if (!last_time || (cur_time - last_time) >= 30000) {
1685 aqsize = is->audioq.size;
1687 vqsize = is->videoq.size;
1688 if (is->subtitle_st)
1689 sqsize = is->subtitleq.size;
1691 if (is->audio_st && is->video_st)
1692 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1693 else if (is->video_st)
1694 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1695 else if (is->audio_st)
1696 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1697 av_log(NULL, AV_LOG_INFO,
1698 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1699 get_master_clock(is),
1700 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1702 is->frame_drops_early + is->frame_drops_late,
1706 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1707 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1709 last_time = cur_time;
1714 /* allocate a picture (needs to do that in main thread to avoid
1715 potential locking problems */
1716 static void alloc_picture(VideoState *is)
1721 vp = &is->pictq.queue[is->pictq.windex];
1725 video_open(is, 0, vp);
1727 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1730 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1731 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1732 /* SDL allocates a buffer smaller than requested if the video
1733 * overlay hardware is unable to support the requested size. */
1734 av_log(NULL, AV_LOG_FATAL,
1735 "Error: the video system does not support an image\n"
1736 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1737 "to reduce the image size.\n", vp->width, vp->height );
1741 SDL_LockMutex(is->pictq.mutex);
1743 SDL_CondSignal(is->pictq.cond);
1744 SDL_UnlockMutex(is->pictq.mutex);
1747 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1748 int i, width, height;
1750 for (i = 0; i < 3; i++) {
1757 if (bmp->pitches[i] > width) {
1758 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1759 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1765 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1769 #if defined(DEBUG_SYNC) && 0
1770 printf("frame_type=%c pts=%0.3f\n",
1771 av_get_picture_type_char(src_frame->pict_type), pts);
1774 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1777 vp->sar = src_frame->sample_aspect_ratio;
1779 /* alloc or resize hardware picture buffer */
1780 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1781 vp->width != src_frame->width ||
1782 vp->height != src_frame->height) {
1787 vp->width = src_frame->width;
1788 vp->height = src_frame->height;
1790 /* the allocation must be done in the main thread to avoid
1791 locking problems. */
1792 event.type = FF_ALLOC_EVENT;
1793 event.user.data1 = is;
1794 SDL_PushEvent(&event);
1796 /* wait until the picture is allocated */
1797 SDL_LockMutex(is->pictq.mutex);
1798 while (!vp->allocated && !is->videoq.abort_request) {
1799 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1801 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1802 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1803 while (!vp->allocated && !is->abort_request) {
1804 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1807 SDL_UnlockMutex(is->pictq.mutex);
1809 if (is->videoq.abort_request)
1813 /* if the frame is not skipped, then display it */
1815 AVPicture pict = { { 0 } };
1817 /* get a pointer on the bitmap */
1818 SDL_LockYUVOverlay (vp->bmp);
1820 pict.data[0] = vp->bmp->pixels[0];
1821 pict.data[1] = vp->bmp->pixels[2];
1822 pict.data[2] = vp->bmp->pixels[1];
1824 pict.linesize[0] = vp->bmp->pitches[0];
1825 pict.linesize[1] = vp->bmp->pitches[2];
1826 pict.linesize[2] = vp->bmp->pitches[1];
1829 // FIXME use direct rendering
1830 av_picture_copy(&pict, (AVPicture *)src_frame,
1831 src_frame->format, vp->width, vp->height);
1833 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1834 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1835 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1836 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1837 if (!is->img_convert_ctx) {
1838 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1841 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1842 0, vp->height, pict.data, pict.linesize);
1844 /* workaround SDL PITCH_WORKAROUND */
1845 duplicate_right_border_pixels(vp->bmp);
1846 /* update the bitmap content */
1847 SDL_UnlockYUVOverlay(vp->bmp);
1850 vp->duration = duration;
1852 vp->serial = serial;
1854 /* now we can update the picture count */
1855 frame_queue_push(&is->pictq);
1860 static int get_video_frame(VideoState *is, AVFrame *frame)
1864 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1870 if (frame->pts != AV_NOPTS_VALUE)
1871 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1873 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1875 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1876 if (frame->pts != AV_NOPTS_VALUE) {
1877 double diff = dpts - get_master_clock(is);
1878 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1879 diff - is->frame_last_filter_delay < 0 &&
1880 is->viddec.pkt_serial == is->vidclk.serial &&
1881 is->videoq.nb_packets) {
1882 is->frame_drops_early++;
1883 av_frame_unref(frame);
1894 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1895 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1898 int nb_filters = graph->nb_filters;
1899 AVFilterInOut *outputs = NULL, *inputs = NULL;
1902 outputs = avfilter_inout_alloc();
1903 inputs = avfilter_inout_alloc();
1904 if (!outputs || !inputs) {
1905 ret = AVERROR(ENOMEM);
1909 outputs->name = av_strdup("in");
1910 outputs->filter_ctx = source_ctx;
1911 outputs->pad_idx = 0;
1912 outputs->next = NULL;
1914 inputs->name = av_strdup("out");
1915 inputs->filter_ctx = sink_ctx;
1916 inputs->pad_idx = 0;
1917 inputs->next = NULL;
1919 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1922 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1926 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1927 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1928 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1930 ret = avfilter_graph_config(graph, NULL);
1932 avfilter_inout_free(&outputs);
1933 avfilter_inout_free(&inputs);
1937 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1939 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1940 char sws_flags_str[128];
1941 char buffersrc_args[256];
1943 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1944 AVCodecContext *codec = is->video_st->codec;
1945 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1947 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1948 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1949 graph->scale_sws_opts = av_strdup(sws_flags_str);
1951 snprintf(buffersrc_args, sizeof(buffersrc_args),
1952 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1953 frame->width, frame->height, frame->format,
1954 is->video_st->time_base.num, is->video_st->time_base.den,
1955 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1956 if (fr.num && fr.den)
1957 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1959 if ((ret = avfilter_graph_create_filter(&filt_src,
1960 avfilter_get_by_name("buffer"),
1961 "ffplay_buffer", buffersrc_args, NULL,
1965 ret = avfilter_graph_create_filter(&filt_out,
1966 avfilter_get_by_name("buffersink"),
1967 "ffplay_buffersink", NULL, NULL, graph);
1971 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1974 last_filter = filt_out;
1976 /* Note: this macro adds a filter before the lastly added filter, so the
1977 * processing order of the filters is in reverse */
1978 #define INSERT_FILT(name, arg) do { \
1979 AVFilterContext *filt_ctx; \
1981 ret = avfilter_graph_create_filter(&filt_ctx, \
1982 avfilter_get_by_name(name), \
1983 "ffplay_" name, arg, NULL, graph); \
1987 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1991 last_filter = filt_ctx; \
1994 /* SDL YUV code is not handling odd width/height for some driver
1995 * combinations, therefore we crop the picture to an even width/height. */
1996 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1999 AVDictionaryEntry *rotate_tag = av_dict_get(is->video_st->metadata, "rotate", NULL, 0);
2000 if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
2001 if (!strcmp(rotate_tag->value, "90")) {
2002 INSERT_FILT("transpose", "clock");
2003 } else if (!strcmp(rotate_tag->value, "180")) {
2004 INSERT_FILT("hflip", NULL);
2005 INSERT_FILT("vflip", NULL);
2006 } else if (!strcmp(rotate_tag->value, "270")) {
2007 INSERT_FILT("transpose", "cclock");
2009 char rotate_buf[64];
2010 snprintf(rotate_buf, sizeof(rotate_buf), "%s*PI/180", rotate_tag->value);
2011 INSERT_FILT("rotate", rotate_buf);
2016 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
2019 is->in_video_filter = filt_src;
2020 is->out_video_filter = filt_out;
2026 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
2028 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2029 int sample_rates[2] = { 0, -1 };
2030 int64_t channel_layouts[2] = { 0, -1 };
2031 int channels[2] = { 0, -1 };
2032 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2033 char aresample_swr_opts[512] = "";
2034 AVDictionaryEntry *e = NULL;
2035 char asrc_args[256];
2038 avfilter_graph_free(&is->agraph);
2039 if (!(is->agraph = avfilter_graph_alloc()))
2040 return AVERROR(ENOMEM);
2042 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2043 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2044 if (strlen(aresample_swr_opts))
2045 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2046 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2048 ret = snprintf(asrc_args, sizeof(asrc_args),
2049 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2050 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2051 is->audio_filter_src.channels,
2052 1, is->audio_filter_src.freq);
2053 if (is->audio_filter_src.channel_layout)
2054 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2055 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2057 ret = avfilter_graph_create_filter(&filt_asrc,
2058 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2059 asrc_args, NULL, is->agraph);
2064 ret = avfilter_graph_create_filter(&filt_asink,
2065 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2066 NULL, NULL, is->agraph);
2070 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2072 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2075 if (force_output_format) {
2076 channel_layouts[0] = is->audio_tgt.channel_layout;
2077 channels [0] = is->audio_tgt.channels;
2078 sample_rates [0] = is->audio_tgt.freq;
2079 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2081 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2083 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2085 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2090 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2093 is->in_audio_filter = filt_asrc;
2094 is->out_audio_filter = filt_asink;
2098 avfilter_graph_free(&is->agraph);
2101 #endif /* CONFIG_AVFILTER */
2103 static int video_thread(void *arg)
2105 VideoState *is = arg;
2106 AVFrame *frame = av_frame_alloc();
2110 AVRational tb = is->video_st->time_base;
2111 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2114 AVFilterGraph *graph = avfilter_graph_alloc();
2115 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2118 enum AVPixelFormat last_format = -2;
2119 int last_serial = -1;
2120 int last_vfilter_idx = 0;
2124 ret = get_video_frame(is, frame);
2131 if ( last_w != frame->width
2132 || last_h != frame->height
2133 || last_format != frame->format
2134 || last_serial != is->viddec.pkt_serial
2135 || last_vfilter_idx != is->vfilter_idx) {
2136 av_log(NULL, AV_LOG_DEBUG,
2137 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2139 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2140 frame->width, frame->height,
2141 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2142 avfilter_graph_free(&graph);
2143 graph = avfilter_graph_alloc();
2144 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2146 event.type = FF_QUIT_EVENT;
2147 event.user.data1 = is;
2148 SDL_PushEvent(&event);
2151 filt_in = is->in_video_filter;
2152 filt_out = is->out_video_filter;
2153 last_w = frame->width;
2154 last_h = frame->height;
2155 last_format = frame->format;
2156 last_serial = is->viddec.pkt_serial;
2157 last_vfilter_idx = is->vfilter_idx;
2158 frame_rate = filt_out->inputs[0]->frame_rate;
2161 ret = av_buffersrc_add_frame(filt_in, frame);
2166 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2168 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2170 if (ret == AVERROR_EOF)
2171 is->viddec.finished = is->viddec.pkt_serial;
2176 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2177 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2178 is->frame_last_filter_delay = 0;
2179 tb = filt_out->inputs[0]->time_base;
2181 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2182 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2183 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2184 av_frame_unref(frame);
2194 avfilter_graph_free(&graph);
2196 av_frame_free(&frame);
2200 static int subtitle_thread(void *arg)
2202 VideoState *is = arg;
2207 int r, g, b, y, u, v, a;
2210 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2213 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2218 if (got_subtitle && sp->sub.format == 0) {
2219 if (sp->sub.pts != AV_NOPTS_VALUE)
2220 pts = sp->sub.pts / (double)AV_TIME_BASE;
2222 sp->serial = is->subdec.pkt_serial;
2224 for (i = 0; i < sp->sub.num_rects; i++)
2226 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2228 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2229 y = RGB_TO_Y_CCIR(r, g, b);
2230 u = RGB_TO_U_CCIR(r, g, b, 0);
2231 v = RGB_TO_V_CCIR(r, g, b, 0);
2232 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2236 /* now we can update the picture count */
2237 frame_queue_push(&is->subpq);
2238 } else if (got_subtitle) {
2239 avsubtitle_free(&sp->sub);
2245 /* copy samples for viewing in editor window */
2246 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2250 size = samples_size / sizeof(short);
2252 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2255 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2257 is->sample_array_index += len;
2258 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2259 is->sample_array_index = 0;
2264 /* return the wanted number of samples to get better sync if sync_type is video
2265 * or external master clock */
2266 static int synchronize_audio(VideoState *is, int nb_samples)
2268 int wanted_nb_samples = nb_samples;
2270 /* if not master, then we try to remove or add samples to correct the clock */
2271 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2272 double diff, avg_diff;
2273 int min_nb_samples, max_nb_samples;
2275 diff = get_clock(&is->audclk) - get_master_clock(is);
2277 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2278 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2279 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2280 /* not enough measures to have a correct estimate */
2281 is->audio_diff_avg_count++;
2283 /* estimate the A-V difference */
2284 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2286 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2287 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2288 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2289 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2290 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2292 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2293 diff, avg_diff, wanted_nb_samples - nb_samples,
2294 is->audio_clock, is->audio_diff_threshold);
2297 /* too big difference : may be initial PTS errors, so
2299 is->audio_diff_avg_count = 0;
2300 is->audio_diff_cum = 0;
2304 return wanted_nb_samples;
2308 * Decode one audio frame and return its uncompressed size.
2310 * The processed audio frame is decoded, converted if required, and
2311 * stored in is->audio_buf, with size in bytes given by the return
2314 static int audio_decode_frame(VideoState *is)
2316 int data_size, resampled_data_size;
2317 int64_t dec_channel_layout;
2319 av_unused double audio_clock0;
2320 int wanted_nb_samples;
2326 if (!(is->frame = av_frame_alloc()))
2327 return AVERROR(ENOMEM);
2330 if (is->audioq.serial != is->auddec.pkt_serial)
2331 is->audio_buf_frames_pending = got_frame = 0;
2334 av_frame_unref(is->frame);
2339 while (is->audio_buf_frames_pending || got_frame) {
2340 if (!is->audio_buf_frames_pending) {
2342 tb = (AVRational){1, is->frame->sample_rate};
2345 dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
2348 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2349 is->frame->format, av_frame_get_channels(is->frame)) ||
2350 is->audio_filter_src.channel_layout != dec_channel_layout ||
2351 is->audio_filter_src.freq != is->frame->sample_rate ||
2352 is->auddec.pkt_serial != is->audio_last_serial;
2355 char buf1[1024], buf2[1024];
2356 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2357 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2358 av_log(NULL, AV_LOG_DEBUG,
2359 "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",
2360 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, is->audio_last_serial,
2361 is->frame->sample_rate, av_frame_get_channels(is->frame), av_get_sample_fmt_name(is->frame->format), buf2, is->auddec.pkt_serial);
2363 is->audio_filter_src.fmt = is->frame->format;
2364 is->audio_filter_src.channels = av_frame_get_channels(is->frame);
2365 is->audio_filter_src.channel_layout = dec_channel_layout;
2366 is->audio_filter_src.freq = is->frame->sample_rate;
2367 is->audio_last_serial = is->auddec.pkt_serial;
2369 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2373 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
2378 if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
2379 if (ret == AVERROR(EAGAIN)) {
2380 is->audio_buf_frames_pending = 0;
2383 if (ret == AVERROR_EOF)
2384 is->auddec.finished = is->auddec.pkt_serial;
2387 is->audio_buf_frames_pending = 1;
2388 tb = is->out_audio_filter->inputs[0]->time_base;
2391 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
2392 is->frame->nb_samples,
2393 is->frame->format, 1);
2395 dec_channel_layout =
2396 (is->frame->channel_layout && av_frame_get_channels(is->frame) == av_get_channel_layout_nb_channels(is->frame->channel_layout)) ?
2397 is->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(is->frame));
2398 wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2400 if (is->frame->format != is->audio_src.fmt ||
2401 dec_channel_layout != is->audio_src.channel_layout ||
2402 is->frame->sample_rate != is->audio_src.freq ||
2403 (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2404 swr_free(&is->swr_ctx);
2405 is->swr_ctx = swr_alloc_set_opts(NULL,
2406 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2407 dec_channel_layout, is->frame->format, is->frame->sample_rate,
2409 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2410 av_log(NULL, AV_LOG_ERROR,
2411 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2412 is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
2413 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2414 swr_free(&is->swr_ctx);
2417 is->audio_src.channel_layout = dec_channel_layout;
2418 is->audio_src.channels = av_frame_get_channels(is->frame);
2419 is->audio_src.freq = is->frame->sample_rate;
2420 is->audio_src.fmt = is->frame->format;
2424 const uint8_t **in = (const uint8_t **)is->frame->extended_data;
2425 uint8_t **out = &is->audio_buf1;
2426 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
2427 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2430 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2433 if (wanted_nb_samples != is->frame->nb_samples) {
2434 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
2435 wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
2436 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2440 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2441 if (!is->audio_buf1)
2442 return AVERROR(ENOMEM);
2443 len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
2445 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2448 if (len2 == out_count) {
2449 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2450 if (swr_init(is->swr_ctx) < 0)
2451 swr_free(&is->swr_ctx);
2453 is->audio_buf = is->audio_buf1;
2454 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2456 is->audio_buf = is->frame->data[0];
2457 resampled_data_size = data_size;
2460 audio_clock0 = is->audio_clock;
2461 /* update the audio clock with the pts */
2462 if (is->frame->pts != AV_NOPTS_VALUE)
2463 is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
2465 is->audio_clock = NAN;
2466 is->audio_clock_serial = is->auddec.pkt_serial;
2469 static double last_clock;
2470 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2471 is->audio_clock - last_clock,
2472 is->audio_clock, audio_clock0);
2473 last_clock = is->audio_clock;
2476 return resampled_data_size;
2479 if ((got_frame = decoder_decode_frame(&is->auddec, is->frame, NULL)) < 0)
2482 if (is->auddec.flushed)
2483 is->audio_buf_frames_pending = 0;
2487 /* prepare a new audio buffer */
2488 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2490 VideoState *is = opaque;
2491 int audio_size, len1;
2493 audio_callback_time = av_gettime_relative();
2496 if (is->audio_buf_index >= is->audio_buf_size) {
2497 audio_size = audio_decode_frame(is);
2498 if (audio_size < 0) {
2499 /* if error, just output silence */
2500 is->audio_buf = is->silence_buf;
2501 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2503 if (is->show_mode != SHOW_MODE_VIDEO)
2504 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2505 is->audio_buf_size = audio_size;
2507 is->audio_buf_index = 0;
2509 len1 = is->audio_buf_size - is->audio_buf_index;
2512 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2515 is->audio_buf_index += len1;
2517 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2518 /* Let's assume the audio driver that is used by SDL has two periods. */
2519 if (!isnan(is->audio_clock)) {
2520 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);
2521 sync_clock_to_slave(&is->extclk, &is->audclk);
2525 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2527 SDL_AudioSpec wanted_spec, spec;
2529 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2530 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2531 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2533 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2535 wanted_nb_channels = atoi(env);
2536 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2538 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2539 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2540 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2542 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2543 wanted_spec.channels = wanted_nb_channels;
2544 wanted_spec.freq = wanted_sample_rate;
2545 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2546 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2549 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2550 next_sample_rate_idx--;
2551 wanted_spec.format = AUDIO_S16SYS;
2552 wanted_spec.silence = 0;
2553 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2554 wanted_spec.callback = sdl_audio_callback;
2555 wanted_spec.userdata = opaque;
2556 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2557 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2558 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2559 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2560 if (!wanted_spec.channels) {
2561 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2562 wanted_spec.channels = wanted_nb_channels;
2563 if (!wanted_spec.freq) {
2564 av_log(NULL, AV_LOG_ERROR,
2565 "No more combinations to try, audio open failed\n");
2569 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2571 if (spec.format != AUDIO_S16SYS) {
2572 av_log(NULL, AV_LOG_ERROR,
2573 "SDL advised audio format %d is not supported!\n", spec.format);
2576 if (spec.channels != wanted_spec.channels) {
2577 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2578 if (!wanted_channel_layout) {
2579 av_log(NULL, AV_LOG_ERROR,
2580 "SDL advised channel count %d is not supported!\n", spec.channels);
2585 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2586 audio_hw_params->freq = spec.freq;
2587 audio_hw_params->channel_layout = wanted_channel_layout;
2588 audio_hw_params->channels = spec.channels;
2589 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2590 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);
2591 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2592 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2598 /* open a given stream. Return 0 if OK */
2599 static int stream_component_open(VideoState *is, int stream_index)
2601 AVFormatContext *ic = is->ic;
2602 AVCodecContext *avctx;
2604 const char *forced_codec_name = NULL;
2606 AVDictionaryEntry *t = NULL;
2607 int sample_rate, nb_channels;
2608 int64_t channel_layout;
2610 int stream_lowres = lowres;
2612 if (stream_index < 0 || stream_index >= ic->nb_streams)
2614 avctx = ic->streams[stream_index]->codec;
2616 codec = avcodec_find_decoder(avctx->codec_id);
2618 switch(avctx->codec_type){
2619 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2620 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2621 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2623 if (forced_codec_name)
2624 codec = avcodec_find_decoder_by_name(forced_codec_name);
2626 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2627 "No codec could be found with name '%s'\n", forced_codec_name);
2628 else av_log(NULL, AV_LOG_WARNING,
2629 "No codec could be found with id %d\n", avctx->codec_id);
2633 avctx->codec_id = codec->id;
2634 if(stream_lowres > av_codec_get_max_lowres(codec)){
2635 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2636 av_codec_get_max_lowres(codec));
2637 stream_lowres = av_codec_get_max_lowres(codec);
2639 av_codec_set_lowres(avctx, stream_lowres);
2641 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2642 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2643 if(codec->capabilities & CODEC_CAP_DR1)
2644 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2646 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2647 if (!av_dict_get(opts, "threads", NULL, 0))
2648 av_dict_set(&opts, "threads", "auto", 0);
2650 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2651 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2652 av_dict_set(&opts, "refcounted_frames", "1", 0);
2653 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2656 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2657 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2658 ret = AVERROR_OPTION_NOT_FOUND;
2662 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2663 switch (avctx->codec_type) {
2664 case AVMEDIA_TYPE_AUDIO:
2669 is->audio_filter_src.freq = avctx->sample_rate;
2670 is->audio_filter_src.channels = avctx->channels;
2671 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2672 is->audio_filter_src.fmt = avctx->sample_fmt;
2673 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2675 link = is->out_audio_filter->inputs[0];
2676 sample_rate = link->sample_rate;
2677 nb_channels = link->channels;
2678 channel_layout = link->channel_layout;
2681 sample_rate = avctx->sample_rate;
2682 nb_channels = avctx->channels;
2683 channel_layout = avctx->channel_layout;
2686 /* prepare audio output */
2687 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2689 is->audio_hw_buf_size = ret;
2690 is->audio_src = is->audio_tgt;
2691 is->audio_buf_size = 0;
2692 is->audio_buf_index = 0;
2694 /* init averaging filter */
2695 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2696 is->audio_diff_avg_count = 0;
2697 /* since we do not have a precise anough audio fifo fullness,
2698 we correct audio sync only if larger than this threshold */
2699 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2701 is->audio_stream = stream_index;
2702 is->audio_st = ic->streams[stream_index];
2704 packet_queue_start(&is->audioq);
2705 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2706 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2707 is->auddec.start_pts = is->audio_st->start_time;
2708 is->auddec.start_pts_tb = is->audio_st->time_base;
2712 case AVMEDIA_TYPE_VIDEO:
2713 is->video_stream = stream_index;
2714 is->video_st = ic->streams[stream_index];
2716 packet_queue_start(&is->videoq);
2717 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2718 is->video_tid = SDL_CreateThread(video_thread, is);
2719 is->queue_attachments_req = 1;
2721 case AVMEDIA_TYPE_SUBTITLE:
2722 is->subtitle_stream = stream_index;
2723 is->subtitle_st = ic->streams[stream_index];
2725 packet_queue_start(&is->subtitleq);
2726 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2727 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2734 av_dict_free(&opts);
2739 static void stream_component_close(VideoState *is, int stream_index)
2741 AVFormatContext *ic = is->ic;
2742 AVCodecContext *avctx;
2744 if (stream_index < 0 || stream_index >= ic->nb_streams)
2746 avctx = ic->streams[stream_index]->codec;
2748 switch (avctx->codec_type) {
2749 case AVMEDIA_TYPE_AUDIO:
2750 packet_queue_abort(&is->audioq);
2754 decoder_destroy(&is->auddec);
2755 packet_queue_flush(&is->audioq);
2756 swr_free(&is->swr_ctx);
2757 av_freep(&is->audio_buf1);
2758 is->audio_buf1_size = 0;
2759 is->audio_buf = NULL;
2760 av_frame_free(&is->frame);
2763 av_rdft_end(is->rdft);
2764 av_freep(&is->rdft_data);
2769 avfilter_graph_free(&is->agraph);
2772 case AVMEDIA_TYPE_VIDEO:
2773 packet_queue_abort(&is->videoq);
2775 /* note: we also signal this mutex to make sure we deblock the
2776 video thread in all cases */
2777 frame_queue_signal(&is->pictq);
2779 SDL_WaitThread(is->video_tid, NULL);
2781 decoder_destroy(&is->viddec);
2782 packet_queue_flush(&is->videoq);
2784 case AVMEDIA_TYPE_SUBTITLE:
2785 packet_queue_abort(&is->subtitleq);
2787 /* note: we also signal this mutex to make sure we deblock the
2788 video thread in all cases */
2789 frame_queue_signal(&is->subpq);
2791 SDL_WaitThread(is->subtitle_tid, NULL);
2793 decoder_destroy(&is->subdec);
2794 packet_queue_flush(&is->subtitleq);
2800 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2801 avcodec_close(avctx);
2802 switch (avctx->codec_type) {
2803 case AVMEDIA_TYPE_AUDIO:
2804 is->audio_st = NULL;
2805 is->audio_stream = -1;
2807 case AVMEDIA_TYPE_VIDEO:
2808 is->video_st = NULL;
2809 is->video_stream = -1;
2811 case AVMEDIA_TYPE_SUBTITLE:
2812 is->subtitle_st = NULL;
2813 is->subtitle_stream = -1;
2820 static int decode_interrupt_cb(void *ctx)
2822 VideoState *is = ctx;
2823 return is->abort_request;
2826 static int is_realtime(AVFormatContext *s)
2828 if( !strcmp(s->iformat->name, "rtp")
2829 || !strcmp(s->iformat->name, "rtsp")
2830 || !strcmp(s->iformat->name, "sdp")
2834 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2835 || !strncmp(s->filename, "udp:", 4)
2842 /* this thread gets the stream from the disk or the network */
2843 static int read_thread(void *arg)
2845 VideoState *is = arg;
2846 AVFormatContext *ic = NULL;
2848 int st_index[AVMEDIA_TYPE_NB];
2849 AVPacket pkt1, *pkt = &pkt1;
2851 int64_t stream_start_time;
2852 int pkt_in_play_range = 0;
2853 AVDictionaryEntry *t;
2854 AVDictionary **opts;
2855 int orig_nb_streams;
2856 SDL_mutex *wait_mutex = SDL_CreateMutex();
2858 memset(st_index, -1, sizeof(st_index));
2859 is->last_video_stream = is->video_stream = -1;
2860 is->last_audio_stream = is->audio_stream = -1;
2861 is->last_subtitle_stream = is->subtitle_stream = -1;
2863 ic = avformat_alloc_context();
2864 ic->interrupt_callback.callback = decode_interrupt_cb;
2865 ic->interrupt_callback.opaque = is;
2866 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2868 print_error(is->filename, err);
2872 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2873 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2874 ret = AVERROR_OPTION_NOT_FOUND;
2880 ic->flags |= AVFMT_FLAG_GENPTS;
2882 av_format_inject_global_side_data(ic);
2884 opts = setup_find_stream_info_opts(ic, codec_opts);
2885 orig_nb_streams = ic->nb_streams;
2887 err = avformat_find_stream_info(ic, opts);
2889 for (i = 0; i < orig_nb_streams; i++)
2890 av_dict_free(&opts[i]);
2894 av_log(NULL, AV_LOG_WARNING,
2895 "%s: could not find codec parameters\n", is->filename);
2901 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2903 if (seek_by_bytes < 0)
2904 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2906 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2908 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2909 window_title = av_asprintf("%s - %s", t->value, input_filename);
2911 /* if seeking requested, we execute it */
2912 if (start_time != AV_NOPTS_VALUE) {
2915 timestamp = start_time;
2916 /* add the stream start time */
2917 if (ic->start_time != AV_NOPTS_VALUE)
2918 timestamp += ic->start_time;
2919 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2921 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2922 is->filename, (double)timestamp / AV_TIME_BASE);
2926 is->realtime = is_realtime(ic);
2928 for (i = 0; i < ic->nb_streams; i++)
2929 ic->streams[i]->discard = AVDISCARD_ALL;
2931 st_index[AVMEDIA_TYPE_VIDEO] =
2932 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2933 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2935 st_index[AVMEDIA_TYPE_AUDIO] =
2936 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2937 wanted_stream[AVMEDIA_TYPE_AUDIO],
2938 st_index[AVMEDIA_TYPE_VIDEO],
2940 if (!video_disable && !subtitle_disable)
2941 st_index[AVMEDIA_TYPE_SUBTITLE] =
2942 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2943 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2944 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2945 st_index[AVMEDIA_TYPE_AUDIO] :
2946 st_index[AVMEDIA_TYPE_VIDEO]),
2949 av_dump_format(ic, 0, is->filename, 0);
2952 is->show_mode = show_mode;
2953 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2954 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2955 AVCodecContext *avctx = st->codec;
2956 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2958 set_default_window_size(avctx->width, avctx->height, sar);
2961 /* open the streams */
2962 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2963 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2967 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2968 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2970 if (is->show_mode == SHOW_MODE_NONE)
2971 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2973 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2974 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2977 if (is->video_stream < 0 && is->audio_stream < 0) {
2978 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2984 if (infinite_buffer < 0 && is->realtime)
2985 infinite_buffer = 1;
2988 if (is->abort_request)
2990 if (is->paused != is->last_paused) {
2991 is->last_paused = is->paused;
2993 is->read_pause_return = av_read_pause(ic);
2997 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2999 (!strcmp(ic->iformat->name, "rtsp") ||
3000 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3001 /* wait 10 ms to avoid trying to get another packet */
3008 int64_t seek_target = is->seek_pos;
3009 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3010 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3011 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3012 // of the seek_pos/seek_rel variables
3014 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3016 av_log(NULL, AV_LOG_ERROR,
3017 "%s: error while seeking\n", is->ic->filename);
3019 if (is->audio_stream >= 0) {
3020 packet_queue_flush(&is->audioq);
3021 packet_queue_put(&is->audioq, &flush_pkt);
3023 if (is->subtitle_stream >= 0) {
3024 packet_queue_flush(&is->subtitleq);
3025 packet_queue_put(&is->subtitleq, &flush_pkt);
3027 if (is->video_stream >= 0) {
3028 packet_queue_flush(&is->videoq);
3029 packet_queue_put(&is->videoq, &flush_pkt);
3031 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3032 set_clock(&is->extclk, NAN, 0);
3034 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3038 is->queue_attachments_req = 1;
3041 step_to_next_frame(is);
3043 if (is->queue_attachments_req) {
3044 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3046 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3048 packet_queue_put(&is->videoq, ©);
3049 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3051 is->queue_attachments_req = 0;
3054 /* if the queue are full, no need to read more */
3055 if (infinite_buffer<1 &&
3056 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3057 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3058 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3059 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3060 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3062 SDL_LockMutex(wait_mutex);
3063 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3064 SDL_UnlockMutex(wait_mutex);
3068 (!is->audio_st || is->auddec.finished == is->audioq.serial) &&
3069 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3070 if (loop != 1 && (!loop || --loop)) {
3071 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3072 } else if (autoexit) {
3078 if (is->video_stream >= 0)
3079 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3080 if (is->audio_stream >= 0)
3081 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3082 if (is->subtitle_stream >= 0)
3083 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3088 ret = av_read_frame(ic, pkt);
3090 if (ret == AVERROR_EOF || avio_feof(ic->pb))
3092 if (ic->pb && ic->pb->error)
3094 SDL_LockMutex(wait_mutex);
3095 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3096 SDL_UnlockMutex(wait_mutex);
3099 /* check if packet is in play range specified by user, then queue, otherwise discard */
3100 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3101 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3102 (pkt->pts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3103 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3104 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3105 <= ((double)duration / 1000000);
3106 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3107 packet_queue_put(&is->audioq, pkt);
3108 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3109 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3110 packet_queue_put(&is->videoq, pkt);
3111 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3112 packet_queue_put(&is->subtitleq, pkt);
3114 av_free_packet(pkt);
3117 /* wait until the end */
3118 while (!is->abort_request) {
3124 /* close each stream */
3125 if (is->audio_stream >= 0)
3126 stream_component_close(is, is->audio_stream);
3127 if (is->video_stream >= 0)
3128 stream_component_close(is, is->video_stream);
3129 if (is->subtitle_stream >= 0)
3130 stream_component_close(is, is->subtitle_stream);
3132 avformat_close_input(&is->ic);
3138 event.type = FF_QUIT_EVENT;
3139 event.user.data1 = is;
3140 SDL_PushEvent(&event);
3142 SDL_DestroyMutex(wait_mutex);
3146 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3150 is = av_mallocz(sizeof(VideoState));
3153 av_strlcpy(is->filename, filename, sizeof(is->filename));
3154 is->iformat = iformat;
3158 /* start video display */
3159 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3161 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3164 packet_queue_init(&is->videoq);
3165 packet_queue_init(&is->audioq);
3166 packet_queue_init(&is->subtitleq);
3168 is->continue_read_thread = SDL_CreateCond();
3170 init_clock(&is->vidclk, &is->videoq.serial);
3171 init_clock(&is->audclk, &is->audioq.serial);
3172 init_clock(&is->extclk, &is->extclk.serial);
3173 is->audio_clock_serial = -1;
3174 is->audio_last_serial = -1;
3175 is->av_sync_type = av_sync_type;
3176 is->read_tid = SDL_CreateThread(read_thread, is);
3177 if (!is->read_tid) {
3185 static void stream_cycle_channel(VideoState *is, int codec_type)
3187 AVFormatContext *ic = is->ic;
3188 int start_index, stream_index;
3191 AVProgram *p = NULL;
3192 int nb_streams = is->ic->nb_streams;
3194 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3195 start_index = is->last_video_stream;
3196 old_index = is->video_stream;
3197 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3198 start_index = is->last_audio_stream;
3199 old_index = is->audio_stream;
3201 start_index = is->last_subtitle_stream;
3202 old_index = is->subtitle_stream;
3204 stream_index = start_index;
3206 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3207 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3209 nb_streams = p->nb_stream_indexes;
3210 for (start_index = 0; start_index < nb_streams; start_index++)
3211 if (p->stream_index[start_index] == stream_index)
3213 if (start_index == nb_streams)
3215 stream_index = start_index;
3220 if (++stream_index >= nb_streams)
3222 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3225 is->last_subtitle_stream = -1;
3228 if (start_index == -1)
3232 if (stream_index == start_index)
3234 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3235 if (st->codec->codec_type == codec_type) {
3236 /* check that parameters are OK */
3237 switch (codec_type) {
3238 case AVMEDIA_TYPE_AUDIO:
3239 if (st->codec->sample_rate != 0 &&
3240 st->codec->channels != 0)
3243 case AVMEDIA_TYPE_VIDEO:
3244 case AVMEDIA_TYPE_SUBTITLE:
3252 if (p && stream_index != -1)
3253 stream_index = p->stream_index[stream_index];
3254 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3255 av_get_media_type_string(codec_type),
3259 stream_component_close(is, old_index);
3260 stream_component_open(is, stream_index);
3264 static void toggle_full_screen(VideoState *is)
3266 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3267 /* OS X needs to reallocate the SDL overlays */
3269 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3270 is->pictq.queue[i].reallocate = 1;
3272 is_full_screen = !is_full_screen;
3273 video_open(is, 1, NULL);
3276 static void toggle_audio_display(VideoState *is)
3278 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3279 int next = is->show_mode;
3281 next = (next + 1) % SHOW_MODE_NB;
3282 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3283 if (is->show_mode != next) {
3284 fill_rectangle(screen,
3285 is->xleft, is->ytop, is->width, is->height,
3287 is->force_refresh = 1;
3288 is->show_mode = next;
3292 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3293 double remaining_time = 0.0;
3295 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3296 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3300 if (remaining_time > 0.0)
3301 av_usleep((int64_t)(remaining_time * 1000000.0));
3302 remaining_time = REFRESH_RATE;
3303 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3304 video_refresh(is, &remaining_time);
3309 static void seek_chapter(VideoState *is, int incr)
3311 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3314 if (!is->ic->nb_chapters)
3317 /* find the current chapter */
3318 for (i = 0; i < is->ic->nb_chapters; i++) {
3319 AVChapter *ch = is->ic->chapters[i];
3320 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3328 if (i >= is->ic->nb_chapters)
3331 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3332 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3333 AV_TIME_BASE_Q), 0, 0);
3336 /* handle an event sent by the GUI */
3337 static void event_loop(VideoState *cur_stream)
3340 double incr, pos, frac;
3344 refresh_loop_wait_event(cur_stream, &event);
3345 switch (event.type) {
3347 if (exit_on_keydown) {
3348 do_exit(cur_stream);
3351 switch (event.key.keysym.sym) {
3354 do_exit(cur_stream);
3357 toggle_full_screen(cur_stream);
3358 cur_stream->force_refresh = 1;
3362 toggle_pause(cur_stream);
3364 case SDLK_s: // S: Step to next frame
3365 step_to_next_frame(cur_stream);
3368 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3371 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3374 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3375 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3376 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3379 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3383 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3384 if (++cur_stream->vfilter_idx >= nb_vfilters)
3385 cur_stream->vfilter_idx = 0;
3387 cur_stream->vfilter_idx = 0;
3388 toggle_audio_display(cur_stream);
3391 toggle_audio_display(cur_stream);
3395 if (cur_stream->ic->nb_chapters <= 1) {
3399 seek_chapter(cur_stream, 1);
3402 if (cur_stream->ic->nb_chapters <= 1) {
3406 seek_chapter(cur_stream, -1);
3420 if (seek_by_bytes) {
3422 if (pos < 0 && cur_stream->video_stream >= 0)
3423 pos = frame_queue_last_pos(&cur_stream->pictq);
3424 if (pos < 0 && cur_stream->audio_stream >= 0 && cur_stream->frame)
3425 pos = av_frame_get_pkt_pos(cur_stream->frame);
3427 pos = avio_tell(cur_stream->ic->pb);
3428 if (cur_stream->ic->bit_rate)
3429 incr *= cur_stream->ic->bit_rate / 8.0;
3433 stream_seek(cur_stream, pos, incr, 1);
3435 pos = get_master_clock(cur_stream);
3437 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3439 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3440 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3441 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3448 case SDL_VIDEOEXPOSE:
3449 cur_stream->force_refresh = 1;
3451 case SDL_MOUSEBUTTONDOWN:
3452 if (exit_on_mousedown) {
3453 do_exit(cur_stream);
3456 case SDL_MOUSEMOTION:
3457 if (cursor_hidden) {
3461 cursor_last_shown = av_gettime_relative();
3462 if (event.type == SDL_MOUSEBUTTONDOWN) {
3465 if (event.motion.state != SDL_PRESSED)
3469 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3470 uint64_t size = avio_size(cur_stream->ic->pb);
3471 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3475 int tns, thh, tmm, tss;
3476 tns = cur_stream->ic->duration / 1000000LL;
3478 tmm = (tns % 3600) / 60;
3480 frac = x / cur_stream->width;
3483 mm = (ns % 3600) / 60;
3485 av_log(NULL, AV_LOG_INFO,
3486 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3487 hh, mm, ss, thh, tmm, tss);
3488 ts = frac * cur_stream->ic->duration;
3489 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3490 ts += cur_stream->ic->start_time;
3491 stream_seek(cur_stream, ts, 0, 0);
3494 case SDL_VIDEORESIZE:
3495 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3496 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3498 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3499 do_exit(cur_stream);
3501 screen_width = cur_stream->width = screen->w;
3502 screen_height = cur_stream->height = screen->h;
3503 cur_stream->force_refresh = 1;
3507 do_exit(cur_stream);
3509 case FF_ALLOC_EVENT:
3510 alloc_picture(event.user.data1);
3518 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3520 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3521 return opt_default(NULL, "video_size", arg);
3524 static int opt_width(void *optctx, const char *opt, const char *arg)
3526 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3530 static int opt_height(void *optctx, const char *opt, const char *arg)
3532 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3536 static int opt_format(void *optctx, const char *opt, const char *arg)
3538 file_iformat = av_find_input_format(arg);
3539 if (!file_iformat) {
3540 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3541 return AVERROR(EINVAL);
3546 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3548 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3549 return opt_default(NULL, "pixel_format", arg);
3552 static int opt_sync(void *optctx, const char *opt, const char *arg)
3554 if (!strcmp(arg, "audio"))
3555 av_sync_type = AV_SYNC_AUDIO_MASTER;
3556 else if (!strcmp(arg, "video"))
3557 av_sync_type = AV_SYNC_VIDEO_MASTER;
3558 else if (!strcmp(arg, "ext"))
3559 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3561 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3567 static int opt_seek(void *optctx, const char *opt, const char *arg)
3569 start_time = parse_time_or_die(opt, arg, 1);
3573 static int opt_duration(void *optctx, const char *opt, const char *arg)
3575 duration = parse_time_or_die(opt, arg, 1);
3579 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3581 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3582 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3583 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3584 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3588 static void opt_input_file(void *optctx, const char *filename)
3590 if (input_filename) {
3591 av_log(NULL, AV_LOG_FATAL,
3592 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3593 filename, input_filename);
3596 if (!strcmp(filename, "-"))
3598 input_filename = filename;
3601 static int opt_codec(void *optctx, const char *opt, const char *arg)
3603 const char *spec = strchr(opt, ':');
3605 av_log(NULL, AV_LOG_ERROR,
3606 "No media specifier was specified in '%s' in option '%s'\n",
3608 return AVERROR(EINVAL);
3612 case 'a' : audio_codec_name = arg; break;
3613 case 's' : subtitle_codec_name = arg; break;
3614 case 'v' : video_codec_name = arg; break;
3616 av_log(NULL, AV_LOG_ERROR,
3617 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3618 return AVERROR(EINVAL);
3625 static const OptionDef options[] = {
3626 #include "cmdutils_common_opts.h"
3627 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3628 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3629 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3630 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3631 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3632 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3633 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3634 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3635 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3636 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3637 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3638 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3639 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3640 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3641 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3642 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3643 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3644 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3645 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3646 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3647 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3648 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3649 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3650 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3651 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3652 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3653 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3654 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3655 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3657 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3658 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3660 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3661 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3662 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3663 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3664 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3665 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3666 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3667 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3668 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3672 static void show_usage(void)
3674 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3675 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3676 av_log(NULL, AV_LOG_INFO, "\n");
3679 void show_help_default(const char *opt, const char *arg)
3681 av_log_set_callback(log_callback_help);
3683 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3684 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3686 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3687 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3688 #if !CONFIG_AVFILTER
3689 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3691 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3693 printf("\nWhile playing:\n"
3695 "f toggle full screen\n"
3697 "a cycle audio channel in the current program\n"
3698 "v cycle video channel\n"
3699 "t cycle subtitle channel in the current program\n"
3701 "w cycle video filters or show modes\n"
3702 "s activate frame-step mode\n"
3703 "left/right seek backward/forward 10 seconds\n"
3704 "down/up seek backward/forward 1 minute\n"
3705 "page down/page up seek backward/forward 10 minutes\n"
3706 "mouse click seek to percentage in file corresponding to fraction of width\n"
3710 static int lockmgr(void **mtx, enum AVLockOp op)
3713 case AV_LOCK_CREATE:
3714 *mtx = SDL_CreateMutex();
3718 case AV_LOCK_OBTAIN:
3719 return !!SDL_LockMutex(*mtx);
3720 case AV_LOCK_RELEASE:
3721 return !!SDL_UnlockMutex(*mtx);
3722 case AV_LOCK_DESTROY:
3723 SDL_DestroyMutex(*mtx);
3729 /* Called from the main */
3730 int main(int argc, char **argv)
3734 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3736 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3737 parse_loglevel(argc, argv, options);
3739 /* register all codecs, demux and protocols */
3741 avdevice_register_all();
3744 avfilter_register_all();
3747 avformat_network_init();
3751 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3752 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3754 show_banner(argc, argv, options);
3756 parse_options(NULL, argc, argv, options, opt_input_file);
3758 if (!input_filename) {
3760 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3761 av_log(NULL, AV_LOG_FATAL,
3762 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3766 if (display_disable) {
3769 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3771 flags &= ~SDL_INIT_AUDIO;
3772 if (display_disable)
3773 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3774 #if !defined(_WIN32) && !defined(__APPLE__)
3775 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3777 if (SDL_Init (flags)) {
3778 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3779 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3783 if (!display_disable) {
3784 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3785 fs_screen_width = vi->current_w;
3786 fs_screen_height = vi->current_h;
3789 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3790 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3791 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3793 if (av_lockmgr_register(lockmgr)) {
3794 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3798 av_init_packet(&flush_pkt);
3799 flush_pkt.data = (uint8_t *)&flush_pkt;
3801 is = stream_open(input_filename, file_iformat);
3803 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");