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;
328 static int workaround_bugs = 1;
330 static int genpts = 0;
331 static int lowres = 0;
332 static int decoder_reorder_pts = -1;
334 static int exit_on_keydown;
335 static int exit_on_mousedown;
337 static int framedrop = -1;
338 static int infinite_buffer = -1;
339 static enum ShowMode show_mode = SHOW_MODE_NONE;
340 static const char *audio_codec_name;
341 static const char *subtitle_codec_name;
342 static const char *video_codec_name;
343 double rdftspeed = 0.02;
344 static int64_t cursor_last_shown;
345 static int cursor_hidden = 0;
347 static const char **vfilters_list = NULL;
348 static int nb_vfilters = 0;
349 static char *afilters = NULL;
351 static int autorotate = 1;
353 /* current context */
354 static int is_full_screen;
355 static int64_t audio_callback_time;
357 static AVPacket flush_pkt;
359 #define FF_ALLOC_EVENT (SDL_USEREVENT)
360 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
362 static SDL_Surface *screen;
365 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
367 GROW_ARRAY(vfilters_list, nb_vfilters);
368 vfilters_list[nb_vfilters - 1] = arg;
374 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
375 enum AVSampleFormat fmt2, int64_t channel_count2)
377 /* If channel count == 1, planar and non-planar formats are the same */
378 if (channel_count1 == 1 && channel_count2 == 1)
379 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
381 return channel_count1 != channel_count2 || fmt1 != fmt2;
385 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
387 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
388 return channel_layout;
393 static void free_picture(Frame *vp);
395 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
397 MyAVPacketList *pkt1;
399 if (q->abort_request)
402 pkt1 = av_malloc(sizeof(MyAVPacketList));
407 if (pkt == &flush_pkt)
409 pkt1->serial = q->serial;
414 q->last_pkt->next = pkt1;
417 q->size += pkt1->pkt.size + sizeof(*pkt1);
418 /* XXX: should duplicate packet data in DV case */
419 SDL_CondSignal(q->cond);
423 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
427 /* duplicate the packet */
428 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
431 SDL_LockMutex(q->mutex);
432 ret = packet_queue_put_private(q, pkt);
433 SDL_UnlockMutex(q->mutex);
435 if (pkt != &flush_pkt && ret < 0)
441 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
443 AVPacket pkt1, *pkt = &pkt1;
447 pkt->stream_index = stream_index;
448 return packet_queue_put(q, pkt);
451 /* packet queue handling */
452 static void packet_queue_init(PacketQueue *q)
454 memset(q, 0, sizeof(PacketQueue));
455 q->mutex = SDL_CreateMutex();
456 q->cond = SDL_CreateCond();
457 q->abort_request = 1;
460 static void packet_queue_flush(PacketQueue *q)
462 MyAVPacketList *pkt, *pkt1;
464 SDL_LockMutex(q->mutex);
465 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
467 av_free_packet(&pkt->pkt);
474 SDL_UnlockMutex(q->mutex);
477 static void packet_queue_destroy(PacketQueue *q)
479 packet_queue_flush(q);
480 SDL_DestroyMutex(q->mutex);
481 SDL_DestroyCond(q->cond);
484 static void packet_queue_abort(PacketQueue *q)
486 SDL_LockMutex(q->mutex);
488 q->abort_request = 1;
490 SDL_CondSignal(q->cond);
492 SDL_UnlockMutex(q->mutex);
495 static void packet_queue_start(PacketQueue *q)
497 SDL_LockMutex(q->mutex);
498 q->abort_request = 0;
499 packet_queue_put_private(q, &flush_pkt);
500 SDL_UnlockMutex(q->mutex);
503 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
504 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
506 MyAVPacketList *pkt1;
509 SDL_LockMutex(q->mutex);
512 if (q->abort_request) {
519 q->first_pkt = pkt1->next;
523 q->size -= pkt1->pkt.size + sizeof(*pkt1);
526 *serial = pkt1->serial;
534 SDL_CondWait(q->cond, q->mutex);
537 SDL_UnlockMutex(q->mutex);
541 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
542 memset(d, 0, sizeof(Decoder));
545 d->empty_queue_cond = empty_queue_cond;
546 d->start_pts = AV_NOPTS_VALUE;
549 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
557 if (d->queue->abort_request)
560 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
563 if (d->queue->nb_packets == 0)
564 SDL_CondSignal(d->empty_queue_cond);
565 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
567 if (pkt.data == flush_pkt.data) {
568 avcodec_flush_buffers(d->avctx);
571 d->next_pts = d->start_pts;
572 d->next_pts_tb = d->start_pts_tb;
574 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
575 av_free_packet(&d->pkt);
576 d->pkt_temp = d->pkt = pkt;
577 d->packet_pending = 1;
580 switch (d->avctx->codec_type) {
581 case AVMEDIA_TYPE_VIDEO:
582 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
584 if (decoder_reorder_pts == -1) {
585 frame->pts = av_frame_get_best_effort_timestamp(frame);
586 } else if (decoder_reorder_pts) {
587 frame->pts = frame->pkt_pts;
589 frame->pts = frame->pkt_dts;
593 case AVMEDIA_TYPE_AUDIO:
594 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
596 AVRational tb = (AVRational){1, frame->sample_rate};
597 if (frame->pts != AV_NOPTS_VALUE)
598 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
599 else if (frame->pkt_pts != AV_NOPTS_VALUE)
600 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
601 else if (d->next_pts != AV_NOPTS_VALUE)
602 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
603 if (frame->pts != AV_NOPTS_VALUE) {
604 d->next_pts = frame->pts + frame->nb_samples;
609 case AVMEDIA_TYPE_SUBTITLE:
610 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
615 d->packet_pending = 0;
618 d->pkt_temp.pts = AV_NOPTS_VALUE;
619 if (d->pkt_temp.data) {
620 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
621 ret = d->pkt_temp.size;
622 d->pkt_temp.data += ret;
623 d->pkt_temp.size -= ret;
624 if (d->pkt_temp.size <= 0)
625 d->packet_pending = 0;
628 d->packet_pending = 0;
629 d->finished = d->pkt_serial;
633 } while (!got_frame && !d->finished);
638 static void decoder_destroy(Decoder *d) {
639 av_free_packet(&d->pkt);
642 static void frame_queue_unref_item(Frame *vp)
644 av_frame_unref(vp->frame);
645 avsubtitle_free(&vp->sub);
648 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
651 memset(f, 0, sizeof(FrameQueue));
652 if (!(f->mutex = SDL_CreateMutex()))
653 return AVERROR(ENOMEM);
654 if (!(f->cond = SDL_CreateCond()))
655 return AVERROR(ENOMEM);
657 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
658 f->keep_last = !!keep_last;
659 for (i = 0; i < f->max_size; i++)
660 if (!(f->queue[i].frame = av_frame_alloc()))
661 return AVERROR(ENOMEM);
665 static void frame_queue_destory(FrameQueue *f)
668 for (i = 0; i < f->max_size; i++) {
669 Frame *vp = &f->queue[i];
670 frame_queue_unref_item(vp);
671 av_frame_free(&vp->frame);
674 SDL_DestroyMutex(f->mutex);
675 SDL_DestroyCond(f->cond);
678 static void frame_queue_signal(FrameQueue *f)
680 SDL_LockMutex(f->mutex);
681 SDL_CondSignal(f->cond);
682 SDL_UnlockMutex(f->mutex);
685 static Frame *frame_queue_peek(FrameQueue *f)
687 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
690 static Frame *frame_queue_peek_next(FrameQueue *f)
692 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
695 static Frame *frame_queue_peek_last(FrameQueue *f)
697 return &f->queue[f->rindex];
700 static Frame *frame_queue_peek_writable(FrameQueue *f)
702 /* wait until we have space to put a new frame */
703 SDL_LockMutex(f->mutex);
704 while (f->size >= f->max_size &&
705 !f->pktq->abort_request) {
706 SDL_CondWait(f->cond, f->mutex);
708 SDL_UnlockMutex(f->mutex);
710 if (f->pktq->abort_request)
713 return &f->queue[f->windex];
716 static void frame_queue_push(FrameQueue *f)
718 if (++f->windex == f->max_size)
720 SDL_LockMutex(f->mutex);
722 SDL_UnlockMutex(f->mutex);
725 static void frame_queue_next(FrameQueue *f)
727 if (f->keep_last && !f->rindex_shown) {
731 frame_queue_unref_item(&f->queue[f->rindex]);
732 if (++f->rindex == f->max_size)
734 SDL_LockMutex(f->mutex);
736 SDL_CondSignal(f->cond);
737 SDL_UnlockMutex(f->mutex);
740 /* jump back to the previous frame if available by resetting rindex_shown */
741 static int frame_queue_prev(FrameQueue *f)
743 int ret = f->rindex_shown;
748 /* return the number of undisplayed frames in the queue */
749 static int frame_queue_nb_remaining(FrameQueue *f)
751 return f->size - f->rindex_shown;
754 /* return last shown position */
755 static int64_t frame_queue_last_pos(FrameQueue *f)
757 Frame *fp = &f->queue[f->rindex];
758 if (f->rindex_shown && fp->serial == f->pktq->serial)
764 static inline void fill_rectangle(SDL_Surface *screen,
765 int x, int y, int w, int h, int color, int update)
772 SDL_FillRect(screen, &rect, color);
773 if (update && w > 0 && h > 0)
774 SDL_UpdateRect(screen, x, y, w, h);
777 /* draw only the border of a rectangle */
778 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
782 /* fill the background */
786 w2 = width - (x + w);
792 h2 = height - (y + h);
795 fill_rectangle(screen,
799 fill_rectangle(screen,
800 xleft + width - w2, ytop,
803 fill_rectangle(screen,
807 fill_rectangle(screen,
808 xleft + w1, ytop + height - h2,
813 #define ALPHA_BLEND(a, oldp, newp, s)\
814 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
816 #define RGBA_IN(r, g, b, a, s)\
818 unsigned int v = ((const uint32_t *)(s))[0];\
819 a = (v >> 24) & 0xff;\
820 r = (v >> 16) & 0xff;\
821 g = (v >> 8) & 0xff;\
825 #define YUVA_IN(y, u, v, a, s, pal)\
827 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
828 a = (val >> 24) & 0xff;\
829 y = (val >> 16) & 0xff;\
830 u = (val >> 8) & 0xff;\
834 #define YUVA_OUT(d, y, u, v, a)\
836 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
842 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
844 int wrap, wrap3, width2, skip2;
845 int y, u, v, a, u1, v1, a1, w, h;
846 uint8_t *lum, *cb, *cr;
849 int dstx, dsty, dstw, dsth;
851 dstw = av_clip(rect->w, 0, imgw);
852 dsth = av_clip(rect->h, 0, imgh);
853 dstx = av_clip(rect->x, 0, imgw - dstw);
854 dsty = av_clip(rect->y, 0, imgh - dsth);
855 lum = dst->data[0] + dsty * dst->linesize[0];
856 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
857 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
859 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
861 wrap = dst->linesize[0];
862 wrap3 = rect->pict.linesize[0];
863 p = rect->pict.data[0];
864 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
872 YUVA_IN(y, u, v, a, p, pal);
873 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
874 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
875 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
881 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
882 YUVA_IN(y, u, v, a, p, pal);
886 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
888 YUVA_IN(y, u, v, a, p + BPP, pal);
892 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
893 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
894 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
901 YUVA_IN(y, u, v, a, p, pal);
902 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
903 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
904 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
908 p += wrap3 - dstw * BPP;
909 lum += wrap - dstw - dstx;
910 cb += dst->linesize[1] - width2 - skip2;
911 cr += dst->linesize[2] - width2 - skip2;
913 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
919 YUVA_IN(y, u, v, a, p, pal);
923 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
926 YUVA_IN(y, u, v, a, p, pal);
930 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
931 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
932 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
938 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
939 YUVA_IN(y, u, v, a, p, pal);
943 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
945 YUVA_IN(y, u, v, a, p + BPP, pal);
949 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
953 YUVA_IN(y, u, v, a, p, pal);
957 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
959 YUVA_IN(y, u, v, a, p + BPP, pal);
963 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
965 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
966 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
970 p += -wrap3 + 2 * BPP;
974 YUVA_IN(y, u, v, a, p, pal);
978 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
981 YUVA_IN(y, u, v, a, p, pal);
985 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
986 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
987 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
993 p += wrap3 + (wrap3 - dstw * BPP);
994 lum += wrap + (wrap - dstw - dstx);
995 cb += dst->linesize[1] - width2 - skip2;
996 cr += dst->linesize[2] - width2 - skip2;
998 /* handle odd height */
1005 YUVA_IN(y, u, v, a, p, pal);
1006 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1007 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1008 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1014 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
1015 YUVA_IN(y, u, v, a, p, pal);
1019 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1021 YUVA_IN(y, u, v, a, p + BPP, pal);
1025 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
1026 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
1027 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
1034 YUVA_IN(y, u, v, a, p, pal);
1035 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1036 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1037 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1042 static void free_picture(Frame *vp)
1045 SDL_FreeYUVOverlay(vp->bmp);
1050 static void calculate_display_rect(SDL_Rect *rect,
1051 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
1052 int pic_width, int pic_height, AVRational pic_sar)
1055 int width, height, x, y;
1057 if (pic_sar.num == 0)
1060 aspect_ratio = av_q2d(pic_sar);
1062 if (aspect_ratio <= 0.0)
1064 aspect_ratio *= (float)pic_width / (float)pic_height;
1066 /* XXX: we suppose the screen has a 1.0 pixel ratio */
1067 height = scr_height;
1068 width = ((int)rint(height * aspect_ratio)) & ~1;
1069 if (width > scr_width) {
1071 height = ((int)rint(width / aspect_ratio)) & ~1;
1073 x = (scr_width - width) / 2;
1074 y = (scr_height - height) / 2;
1075 rect->x = scr_xleft + x;
1076 rect->y = scr_ytop + y;
1077 rect->w = FFMAX(width, 1);
1078 rect->h = FFMAX(height, 1);
1081 static void video_image_display(VideoState *is)
1089 vp = frame_queue_peek(&is->pictq);
1091 if (is->subtitle_st) {
1092 if (frame_queue_nb_remaining(&is->subpq) > 0) {
1093 sp = frame_queue_peek(&is->subpq);
1095 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
1096 SDL_LockYUVOverlay (vp->bmp);
1098 pict.data[0] = vp->bmp->pixels[0];
1099 pict.data[1] = vp->bmp->pixels[2];
1100 pict.data[2] = vp->bmp->pixels[1];
1102 pict.linesize[0] = vp->bmp->pitches[0];
1103 pict.linesize[1] = vp->bmp->pitches[2];
1104 pict.linesize[2] = vp->bmp->pitches[1];
1106 for (i = 0; i < sp->sub.num_rects; i++)
1107 blend_subrect(&pict, sp->sub.rects[i],
1108 vp->bmp->w, vp->bmp->h);
1110 SDL_UnlockYUVOverlay (vp->bmp);
1115 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1117 SDL_DisplayYUVOverlay(vp->bmp, &rect);
1119 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) {
1120 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1121 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
1122 is->last_display_rect = rect;
1127 static inline int compute_mod(int a, int b)
1129 return a < 0 ? a%b + b : a%b;
1132 static void video_audio_display(VideoState *s)
1134 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1135 int ch, channels, h, h2, bgcolor, fgcolor;
1137 int rdft_bits, nb_freq;
1139 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1141 nb_freq = 1 << (rdft_bits - 1);
1143 /* compute display index : center on currently output samples */
1144 channels = s->audio_tgt.channels;
1145 nb_display_channels = channels;
1147 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1149 delay = s->audio_write_buf_size;
1152 /* to be more precise, we take into account the time spent since
1153 the last buffer computation */
1154 if (audio_callback_time) {
1155 time_diff = av_gettime_relative() - audio_callback_time;
1156 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1159 delay += 2 * data_used;
1160 if (delay < data_used)
1163 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1164 if (s->show_mode == SHOW_MODE_WAVES) {
1166 for (i = 0; i < 1000; i += channels) {
1167 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1168 int a = s->sample_array[idx];
1169 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1170 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1171 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1173 if (h < score && (b ^ c) < 0) {
1180 s->last_i_start = i_start;
1182 i_start = s->last_i_start;
1185 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1186 if (s->show_mode == SHOW_MODE_WAVES) {
1187 fill_rectangle(screen,
1188 s->xleft, s->ytop, s->width, s->height,
1191 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1193 /* total height for one channel */
1194 h = s->height / nb_display_channels;
1195 /* graph height / 2 */
1197 for (ch = 0; ch < nb_display_channels; ch++) {
1199 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1200 for (x = 0; x < s->width; x++) {
1201 y = (s->sample_array[i] * h2) >> 15;
1208 fill_rectangle(screen,
1209 s->xleft + x, ys, 1, y,
1212 if (i >= SAMPLE_ARRAY_SIZE)
1213 i -= SAMPLE_ARRAY_SIZE;
1217 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1219 for (ch = 1; ch < nb_display_channels; ch++) {
1220 y = s->ytop + ch * h;
1221 fill_rectangle(screen,
1222 s->xleft, y, s->width, 1,
1225 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1227 nb_display_channels= FFMIN(nb_display_channels, 2);
1228 if (rdft_bits != s->rdft_bits) {
1229 av_rdft_end(s->rdft);
1230 av_free(s->rdft_data);
1231 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1232 s->rdft_bits = rdft_bits;
1233 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1237 for (ch = 0; ch < nb_display_channels; ch++) {
1238 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1240 for (x = 0; x < 2 * nb_freq; x++) {
1241 double w = (x-nb_freq) * (1.0 / nb_freq);
1242 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1244 if (i >= SAMPLE_ARRAY_SIZE)
1245 i -= SAMPLE_ARRAY_SIZE;
1247 av_rdft_calc(s->rdft, data[ch]);
1249 /* Least efficient way to do this, we should of course
1250 * directly access it but it is more than fast enough. */
1251 for (y = 0; y < s->height; y++) {
1252 double w = 1 / sqrt(nb_freq);
1253 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]));
1254 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1255 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1258 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1260 fill_rectangle(screen,
1261 s->xpos, s->height-y, 1, 1,
1265 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1268 if (s->xpos >= s->width)
1273 static void stream_close(VideoState *is)
1275 /* XXX: use a special url_shutdown call to abort parse cleanly */
1276 is->abort_request = 1;
1277 SDL_WaitThread(is->read_tid, NULL);
1278 packet_queue_destroy(&is->videoq);
1279 packet_queue_destroy(&is->audioq);
1280 packet_queue_destroy(&is->subtitleq);
1282 /* free all pictures */
1283 frame_queue_destory(&is->pictq);
1284 frame_queue_destory(&is->subpq);
1285 SDL_DestroyCond(is->continue_read_thread);
1286 #if !CONFIG_AVFILTER
1287 sws_freeContext(is->img_convert_ctx);
1292 static void do_exit(VideoState *is)
1297 av_lockmgr_register(NULL);
1300 av_freep(&vfilters_list);
1302 avformat_network_deinit();
1306 av_log(NULL, AV_LOG_QUIET, "%s", "");
1310 static void sigterm_handler(int sig)
1315 static void set_default_window_size(int width, int height, AVRational sar)
1318 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1319 default_width = rect.w;
1320 default_height = rect.h;
1323 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1325 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1328 if (is_full_screen) flags |= SDL_FULLSCREEN;
1329 else flags |= SDL_RESIZABLE;
1331 if (vp && vp->width)
1332 set_default_window_size(vp->width, vp->height, vp->sar);
1334 if (is_full_screen && fs_screen_width) {
1335 w = fs_screen_width;
1336 h = fs_screen_height;
1337 } else if (!is_full_screen && screen_width) {
1344 w = FFMIN(16383, w);
1345 if (screen && is->width == screen->w && screen->w == w
1346 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1348 screen = SDL_SetVideoMode(w, h, 0, flags);
1350 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1354 window_title = input_filename;
1355 SDL_WM_SetCaption(window_title, window_title);
1357 is->width = screen->w;
1358 is->height = screen->h;
1363 /* display the current picture, if any */
1364 static void video_display(VideoState *is)
1367 video_open(is, 0, NULL);
1368 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1369 video_audio_display(is);
1370 else if (is->video_st)
1371 video_image_display(is);
1374 static double get_clock(Clock *c)
1376 if (*c->queue_serial != c->serial)
1381 double time = av_gettime_relative() / 1000000.0;
1382 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1386 static void set_clock_at(Clock *c, double pts, int serial, double time)
1389 c->last_updated = time;
1390 c->pts_drift = c->pts - time;
1394 static void set_clock(Clock *c, double pts, int serial)
1396 double time = av_gettime_relative() / 1000000.0;
1397 set_clock_at(c, pts, serial, time);
1400 static void set_clock_speed(Clock *c, double speed)
1402 set_clock(c, get_clock(c), c->serial);
1406 static void init_clock(Clock *c, int *queue_serial)
1410 c->queue_serial = queue_serial;
1411 set_clock(c, NAN, -1);
1414 static void sync_clock_to_slave(Clock *c, Clock *slave)
1416 double clock = get_clock(c);
1417 double slave_clock = get_clock(slave);
1418 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1419 set_clock(c, slave_clock, slave->serial);
1422 static int get_master_sync_type(VideoState *is) {
1423 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1425 return AV_SYNC_VIDEO_MASTER;
1427 return AV_SYNC_AUDIO_MASTER;
1428 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1430 return AV_SYNC_AUDIO_MASTER;
1432 return AV_SYNC_EXTERNAL_CLOCK;
1434 return AV_SYNC_EXTERNAL_CLOCK;
1438 /* get the current master clock value */
1439 static double get_master_clock(VideoState *is)
1443 switch (get_master_sync_type(is)) {
1444 case AV_SYNC_VIDEO_MASTER:
1445 val = get_clock(&is->vidclk);
1447 case AV_SYNC_AUDIO_MASTER:
1448 val = get_clock(&is->audclk);
1451 val = get_clock(&is->extclk);
1457 static void check_external_clock_speed(VideoState *is) {
1458 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1459 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1460 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1461 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1462 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1463 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1465 double speed = is->extclk.speed;
1467 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1471 /* seek in the stream */
1472 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1474 if (!is->seek_req) {
1477 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1479 is->seek_flags |= AVSEEK_FLAG_BYTE;
1481 SDL_CondSignal(is->continue_read_thread);
1485 /* pause or resume the video */
1486 static void stream_toggle_pause(VideoState *is)
1489 is->frame_timer += av_gettime_relative() / 1000000.0 + is->vidclk.pts_drift - is->vidclk.pts;
1490 if (is->read_pause_return != AVERROR(ENOSYS)) {
1491 is->vidclk.paused = 0;
1493 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1495 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1496 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1499 static void toggle_pause(VideoState *is)
1501 stream_toggle_pause(is);
1505 static void step_to_next_frame(VideoState *is)
1507 /* if the stream is paused unpause it, then step */
1509 stream_toggle_pause(is);
1513 static double compute_target_delay(double delay, VideoState *is)
1515 double sync_threshold, diff;
1517 /* update delay to follow master synchronisation source */
1518 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1519 /* if video is slave, we try to correct big delays by
1520 duplicating or deleting a frame */
1521 diff = get_clock(&is->vidclk) - get_master_clock(is);
1523 /* skip or repeat frame. We take into account the
1524 delay to compute the threshold. I still don't know
1525 if it is the best guess */
1526 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1527 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1528 if (diff <= -sync_threshold)
1529 delay = FFMAX(0, delay + diff);
1530 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1531 delay = delay + diff;
1532 else if (diff >= sync_threshold)
1537 av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1543 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1544 if (vp->serial == nextvp->serial) {
1545 double duration = nextvp->pts - vp->pts;
1546 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1547 return vp->duration;
1555 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1556 /* update current video pts */
1557 set_clock(&is->vidclk, pts, serial);
1558 sync_clock_to_slave(&is->extclk, &is->vidclk);
1561 /* called to display each frame */
1562 static void video_refresh(void *opaque, double *remaining_time)
1564 VideoState *is = opaque;
1569 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1570 check_external_clock_speed(is);
1572 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1573 time = av_gettime_relative() / 1000000.0;
1574 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1576 is->last_vis_time = time;
1578 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1583 if (is->force_refresh)
1584 redisplay = frame_queue_prev(&is->pictq);
1586 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1587 // nothing to do, no picture to display in the queue
1589 double last_duration, duration, delay;
1592 /* dequeue the picture */
1593 lastvp = frame_queue_peek_last(&is->pictq);
1594 vp = frame_queue_peek(&is->pictq);
1596 if (vp->serial != is->videoq.serial) {
1597 frame_queue_next(&is->pictq);
1602 if (lastvp->serial != vp->serial && !redisplay)
1603 is->frame_timer = av_gettime_relative() / 1000000.0;
1608 /* compute nominal last_duration */
1609 last_duration = vp_duration(is, lastvp, vp);
1613 delay = compute_target_delay(last_duration, is);
1615 time= av_gettime_relative()/1000000.0;
1616 if (time < is->frame_timer + delay && !redisplay) {
1617 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1621 is->frame_timer += delay;
1622 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1623 is->frame_timer = time;
1625 SDL_LockMutex(is->pictq.mutex);
1626 if (!redisplay && !isnan(vp->pts))
1627 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1628 SDL_UnlockMutex(is->pictq.mutex);
1630 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1631 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1632 duration = vp_duration(is, vp, nextvp);
1633 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1635 is->frame_drops_late++;
1636 frame_queue_next(&is->pictq);
1642 if (is->subtitle_st) {
1643 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1644 sp = frame_queue_peek(&is->subpq);
1646 if (frame_queue_nb_remaining(&is->subpq) > 1)
1647 sp2 = frame_queue_peek_next(&is->subpq);
1651 if (sp->serial != is->subtitleq.serial
1652 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1653 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1655 frame_queue_next(&is->subpq);
1663 /* display picture */
1664 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1667 frame_queue_next(&is->pictq);
1669 if (is->step && !is->paused)
1670 stream_toggle_pause(is);
1673 is->force_refresh = 0;
1675 static int64_t last_time;
1677 int aqsize, vqsize, sqsize;
1680 cur_time = av_gettime_relative();
1681 if (!last_time || (cur_time - last_time) >= 30000) {
1686 aqsize = is->audioq.size;
1688 vqsize = is->videoq.size;
1689 if (is->subtitle_st)
1690 sqsize = is->subtitleq.size;
1692 if (is->audio_st && is->video_st)
1693 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1694 else if (is->video_st)
1695 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1696 else if (is->audio_st)
1697 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1698 av_log(NULL, AV_LOG_INFO,
1699 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1700 get_master_clock(is),
1701 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1703 is->frame_drops_early + is->frame_drops_late,
1707 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1708 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1710 last_time = cur_time;
1715 /* allocate a picture (needs to do that in main thread to avoid
1716 potential locking problems */
1717 static void alloc_picture(VideoState *is)
1722 vp = &is->pictq.queue[is->pictq.windex];
1726 video_open(is, 0, vp);
1728 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1731 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1732 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1733 /* SDL allocates a buffer smaller than requested if the video
1734 * overlay hardware is unable to support the requested size. */
1735 av_log(NULL, AV_LOG_FATAL,
1736 "Error: the video system does not support an image\n"
1737 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1738 "to reduce the image size.\n", vp->width, vp->height );
1742 SDL_LockMutex(is->pictq.mutex);
1744 SDL_CondSignal(is->pictq.cond);
1745 SDL_UnlockMutex(is->pictq.mutex);
1748 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1749 int i, width, height;
1751 for (i = 0; i < 3; i++) {
1758 if (bmp->pitches[i] > width) {
1759 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1760 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1766 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1770 #if defined(DEBUG_SYNC) && 0
1771 printf("frame_type=%c pts=%0.3f\n",
1772 av_get_picture_type_char(src_frame->pict_type), pts);
1775 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1778 vp->sar = src_frame->sample_aspect_ratio;
1780 /* alloc or resize hardware picture buffer */
1781 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1782 vp->width != src_frame->width ||
1783 vp->height != src_frame->height) {
1788 vp->width = src_frame->width;
1789 vp->height = src_frame->height;
1791 /* the allocation must be done in the main thread to avoid
1792 locking problems. */
1793 event.type = FF_ALLOC_EVENT;
1794 event.user.data1 = is;
1795 SDL_PushEvent(&event);
1797 /* wait until the picture is allocated */
1798 SDL_LockMutex(is->pictq.mutex);
1799 while (!vp->allocated && !is->videoq.abort_request) {
1800 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1802 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1803 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1804 while (!vp->allocated && !is->abort_request) {
1805 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1808 SDL_UnlockMutex(is->pictq.mutex);
1810 if (is->videoq.abort_request)
1814 /* if the frame is not skipped, then display it */
1816 AVPicture pict = { { 0 } };
1818 /* get a pointer on the bitmap */
1819 SDL_LockYUVOverlay (vp->bmp);
1821 pict.data[0] = vp->bmp->pixels[0];
1822 pict.data[1] = vp->bmp->pixels[2];
1823 pict.data[2] = vp->bmp->pixels[1];
1825 pict.linesize[0] = vp->bmp->pitches[0];
1826 pict.linesize[1] = vp->bmp->pitches[2];
1827 pict.linesize[2] = vp->bmp->pitches[1];
1830 // FIXME use direct rendering
1831 av_picture_copy(&pict, (AVPicture *)src_frame,
1832 src_frame->format, vp->width, vp->height);
1834 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1835 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1836 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1837 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1838 if (!is->img_convert_ctx) {
1839 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1842 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1843 0, vp->height, pict.data, pict.linesize);
1845 /* workaround SDL PITCH_WORKAROUND */
1846 duplicate_right_border_pixels(vp->bmp);
1847 /* update the bitmap content */
1848 SDL_UnlockYUVOverlay(vp->bmp);
1851 vp->duration = duration;
1853 vp->serial = serial;
1855 /* now we can update the picture count */
1856 frame_queue_push(&is->pictq);
1861 static int get_video_frame(VideoState *is, AVFrame *frame)
1865 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1871 if (frame->pts != AV_NOPTS_VALUE)
1872 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1874 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1876 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1877 if (frame->pts != AV_NOPTS_VALUE) {
1878 double diff = dpts - get_master_clock(is);
1879 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1880 diff - is->frame_last_filter_delay < 0 &&
1881 is->viddec.pkt_serial == is->vidclk.serial &&
1882 is->videoq.nb_packets) {
1883 is->frame_drops_early++;
1884 av_frame_unref(frame);
1895 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1896 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1899 int nb_filters = graph->nb_filters;
1900 AVFilterInOut *outputs = NULL, *inputs = NULL;
1903 outputs = avfilter_inout_alloc();
1904 inputs = avfilter_inout_alloc();
1905 if (!outputs || !inputs) {
1906 ret = AVERROR(ENOMEM);
1910 outputs->name = av_strdup("in");
1911 outputs->filter_ctx = source_ctx;
1912 outputs->pad_idx = 0;
1913 outputs->next = NULL;
1915 inputs->name = av_strdup("out");
1916 inputs->filter_ctx = sink_ctx;
1917 inputs->pad_idx = 0;
1918 inputs->next = NULL;
1920 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1923 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1927 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1928 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1929 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1931 ret = avfilter_graph_config(graph, NULL);
1933 avfilter_inout_free(&outputs);
1934 avfilter_inout_free(&inputs);
1938 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1940 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1941 char sws_flags_str[128];
1942 char buffersrc_args[256];
1944 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1945 AVCodecContext *codec = is->video_st->codec;
1946 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1948 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1949 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1950 graph->scale_sws_opts = av_strdup(sws_flags_str);
1952 snprintf(buffersrc_args, sizeof(buffersrc_args),
1953 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1954 frame->width, frame->height, frame->format,
1955 is->video_st->time_base.num, is->video_st->time_base.den,
1956 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1957 if (fr.num && fr.den)
1958 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1960 if ((ret = avfilter_graph_create_filter(&filt_src,
1961 avfilter_get_by_name("buffer"),
1962 "ffplay_buffer", buffersrc_args, NULL,
1966 ret = avfilter_graph_create_filter(&filt_out,
1967 avfilter_get_by_name("buffersink"),
1968 "ffplay_buffersink", NULL, NULL, graph);
1972 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1975 last_filter = filt_out;
1977 /* Note: this macro adds a filter before the lastly added filter, so the
1978 * processing order of the filters is in reverse */
1979 #define INSERT_FILT(name, arg) do { \
1980 AVFilterContext *filt_ctx; \
1982 ret = avfilter_graph_create_filter(&filt_ctx, \
1983 avfilter_get_by_name(name), \
1984 "ffplay_" name, arg, NULL, graph); \
1988 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1992 last_filter = filt_ctx; \
1995 /* SDL YUV code is not handling odd width/height for some driver
1996 * combinations, therefore we crop the picture to an even width/height. */
1997 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
2000 AVDictionaryEntry *rotate_tag = av_dict_get(is->video_st->metadata, "rotate", NULL, 0);
2001 if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
2002 if (!strcmp(rotate_tag->value, "90")) {
2003 INSERT_FILT("transpose", "clock");
2004 } else if (!strcmp(rotate_tag->value, "180")) {
2005 INSERT_FILT("hflip", NULL);
2006 INSERT_FILT("vflip", NULL);
2007 } else if (!strcmp(rotate_tag->value, "270")) {
2008 INSERT_FILT("transpose", "cclock");
2010 char rotate_buf[64];
2011 snprintf(rotate_buf, sizeof(rotate_buf), "%s*PI/180", rotate_tag->value);
2012 INSERT_FILT("rotate", rotate_buf);
2017 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
2020 is->in_video_filter = filt_src;
2021 is->out_video_filter = filt_out;
2027 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
2029 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
2030 int sample_rates[2] = { 0, -1 };
2031 int64_t channel_layouts[2] = { 0, -1 };
2032 int channels[2] = { 0, -1 };
2033 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
2034 char aresample_swr_opts[512] = "";
2035 AVDictionaryEntry *e = NULL;
2036 char asrc_args[256];
2039 avfilter_graph_free(&is->agraph);
2040 if (!(is->agraph = avfilter_graph_alloc()))
2041 return AVERROR(ENOMEM);
2043 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
2044 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
2045 if (strlen(aresample_swr_opts))
2046 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
2047 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
2049 ret = snprintf(asrc_args, sizeof(asrc_args),
2050 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2051 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
2052 is->audio_filter_src.channels,
2053 1, is->audio_filter_src.freq);
2054 if (is->audio_filter_src.channel_layout)
2055 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
2056 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
2058 ret = avfilter_graph_create_filter(&filt_asrc,
2059 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2060 asrc_args, NULL, is->agraph);
2065 ret = avfilter_graph_create_filter(&filt_asink,
2066 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2067 NULL, NULL, is->agraph);
2071 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
2073 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
2076 if (force_output_format) {
2077 channel_layouts[0] = is->audio_tgt.channel_layout;
2078 channels [0] = is->audio_tgt.channels;
2079 sample_rates [0] = is->audio_tgt.freq;
2080 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
2082 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2084 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2086 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
2091 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2094 is->in_audio_filter = filt_asrc;
2095 is->out_audio_filter = filt_asink;
2099 avfilter_graph_free(&is->agraph);
2102 #endif /* CONFIG_AVFILTER */
2104 static int video_thread(void *arg)
2106 VideoState *is = arg;
2107 AVFrame *frame = av_frame_alloc();
2111 AVRational tb = is->video_st->time_base;
2112 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2115 AVFilterGraph *graph = avfilter_graph_alloc();
2116 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2119 enum AVPixelFormat last_format = -2;
2120 int last_serial = -1;
2121 int last_vfilter_idx = 0;
2125 while (is->paused && !is->videoq.abort_request)
2128 ret = get_video_frame(is, frame);
2135 if ( last_w != frame->width
2136 || last_h != frame->height
2137 || last_format != frame->format
2138 || last_serial != is->viddec.pkt_serial
2139 || last_vfilter_idx != is->vfilter_idx) {
2140 av_log(NULL, AV_LOG_DEBUG,
2141 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2143 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2144 frame->width, frame->height,
2145 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2146 avfilter_graph_free(&graph);
2147 graph = avfilter_graph_alloc();
2148 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2150 event.type = FF_QUIT_EVENT;
2151 event.user.data1 = is;
2152 SDL_PushEvent(&event);
2155 filt_in = is->in_video_filter;
2156 filt_out = is->out_video_filter;
2157 last_w = frame->width;
2158 last_h = frame->height;
2159 last_format = frame->format;
2160 last_serial = is->viddec.pkt_serial;
2161 last_vfilter_idx = is->vfilter_idx;
2162 frame_rate = filt_out->inputs[0]->frame_rate;
2165 ret = av_buffersrc_add_frame(filt_in, frame);
2170 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2172 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2174 if (ret == AVERROR_EOF)
2175 is->viddec.finished = is->viddec.pkt_serial;
2180 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2181 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2182 is->frame_last_filter_delay = 0;
2183 tb = filt_out->inputs[0]->time_base;
2185 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2186 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2187 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2188 av_frame_unref(frame);
2198 avfilter_graph_free(&graph);
2200 av_frame_free(&frame);
2204 static int subtitle_thread(void *arg)
2206 VideoState *is = arg;
2211 int r, g, b, y, u, v, a;
2214 while (is->paused && !is->subtitleq.abort_request) {
2218 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2221 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2226 if (got_subtitle && sp->sub.format == 0) {
2227 if (sp->sub.pts != AV_NOPTS_VALUE)
2228 pts = sp->sub.pts / (double)AV_TIME_BASE;
2230 sp->serial = is->subdec.pkt_serial;
2232 for (i = 0; i < sp->sub.num_rects; i++)
2234 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2236 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2237 y = RGB_TO_Y_CCIR(r, g, b);
2238 u = RGB_TO_U_CCIR(r, g, b, 0);
2239 v = RGB_TO_V_CCIR(r, g, b, 0);
2240 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2244 /* now we can update the picture count */
2245 frame_queue_push(&is->subpq);
2246 } else if (got_subtitle) {
2247 avsubtitle_free(&sp->sub);
2253 /* copy samples for viewing in editor window */
2254 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2258 size = samples_size / sizeof(short);
2260 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2263 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2265 is->sample_array_index += len;
2266 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2267 is->sample_array_index = 0;
2272 /* return the wanted number of samples to get better sync if sync_type is video
2273 * or external master clock */
2274 static int synchronize_audio(VideoState *is, int nb_samples)
2276 int wanted_nb_samples = nb_samples;
2278 /* if not master, then we try to remove or add samples to correct the clock */
2279 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2280 double diff, avg_diff;
2281 int min_nb_samples, max_nb_samples;
2283 diff = get_clock(&is->audclk) - get_master_clock(is);
2285 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2286 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2287 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2288 /* not enough measures to have a correct estimate */
2289 is->audio_diff_avg_count++;
2291 /* estimate the A-V difference */
2292 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2294 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2295 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2296 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2297 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2298 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2300 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2301 diff, avg_diff, wanted_nb_samples - nb_samples,
2302 is->audio_clock, is->audio_diff_threshold);
2305 /* too big difference : may be initial PTS errors, so
2307 is->audio_diff_avg_count = 0;
2308 is->audio_diff_cum = 0;
2312 return wanted_nb_samples;
2316 * Decode one audio frame and return its uncompressed size.
2318 * The processed audio frame is decoded, converted if required, and
2319 * stored in is->audio_buf, with size in bytes given by the return
2322 static int audio_decode_frame(VideoState *is)
2324 int data_size, resampled_data_size;
2325 int64_t dec_channel_layout;
2327 av_unused double audio_clock0;
2328 int wanted_nb_samples;
2334 if (!(is->frame = av_frame_alloc()))
2335 return AVERROR(ENOMEM);
2338 if (is->audioq.serial != is->auddec.pkt_serial)
2339 is->audio_buf_frames_pending = got_frame = 0;
2342 av_frame_unref(is->frame);
2347 while (is->audio_buf_frames_pending || got_frame) {
2348 if (!is->audio_buf_frames_pending) {
2350 tb = (AVRational){1, is->frame->sample_rate};
2353 dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
2356 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2357 is->frame->format, av_frame_get_channels(is->frame)) ||
2358 is->audio_filter_src.channel_layout != dec_channel_layout ||
2359 is->audio_filter_src.freq != is->frame->sample_rate ||
2360 is->auddec.pkt_serial != is->audio_last_serial;
2363 char buf1[1024], buf2[1024];
2364 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2365 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2366 av_log(NULL, AV_LOG_DEBUG,
2367 "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",
2368 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,
2369 is->frame->sample_rate, av_frame_get_channels(is->frame), av_get_sample_fmt_name(is->frame->format), buf2, is->auddec.pkt_serial);
2371 is->audio_filter_src.fmt = is->frame->format;
2372 is->audio_filter_src.channels = av_frame_get_channels(is->frame);
2373 is->audio_filter_src.channel_layout = dec_channel_layout;
2374 is->audio_filter_src.freq = is->frame->sample_rate;
2375 is->audio_last_serial = is->auddec.pkt_serial;
2377 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2381 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
2386 if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
2387 if (ret == AVERROR(EAGAIN)) {
2388 is->audio_buf_frames_pending = 0;
2391 if (ret == AVERROR_EOF)
2392 is->auddec.finished = is->auddec.pkt_serial;
2395 is->audio_buf_frames_pending = 1;
2396 tb = is->out_audio_filter->inputs[0]->time_base;
2399 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
2400 is->frame->nb_samples,
2401 is->frame->format, 1);
2403 dec_channel_layout =
2404 (is->frame->channel_layout && av_frame_get_channels(is->frame) == av_get_channel_layout_nb_channels(is->frame->channel_layout)) ?
2405 is->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(is->frame));
2406 wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2408 if (is->frame->format != is->audio_src.fmt ||
2409 dec_channel_layout != is->audio_src.channel_layout ||
2410 is->frame->sample_rate != is->audio_src.freq ||
2411 (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2412 swr_free(&is->swr_ctx);
2413 is->swr_ctx = swr_alloc_set_opts(NULL,
2414 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2415 dec_channel_layout, is->frame->format, is->frame->sample_rate,
2417 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2418 av_log(NULL, AV_LOG_ERROR,
2419 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2420 is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
2421 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2424 is->audio_src.channel_layout = dec_channel_layout;
2425 is->audio_src.channels = av_frame_get_channels(is->frame);
2426 is->audio_src.freq = is->frame->sample_rate;
2427 is->audio_src.fmt = is->frame->format;
2431 const uint8_t **in = (const uint8_t **)is->frame->extended_data;
2432 uint8_t **out = &is->audio_buf1;
2433 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
2434 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2437 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2440 if (wanted_nb_samples != is->frame->nb_samples) {
2441 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
2442 wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
2443 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2447 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2448 if (!is->audio_buf1)
2449 return AVERROR(ENOMEM);
2450 len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
2452 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2455 if (len2 == out_count) {
2456 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2457 swr_init(is->swr_ctx);
2459 is->audio_buf = is->audio_buf1;
2460 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2462 is->audio_buf = is->frame->data[0];
2463 resampled_data_size = data_size;
2466 audio_clock0 = is->audio_clock;
2467 /* update the audio clock with the pts */
2468 if (is->frame->pts != AV_NOPTS_VALUE)
2469 is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
2471 is->audio_clock = NAN;
2472 is->audio_clock_serial = is->auddec.pkt_serial;
2475 static double last_clock;
2476 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2477 is->audio_clock - last_clock,
2478 is->audio_clock, audio_clock0);
2479 last_clock = is->audio_clock;
2482 return resampled_data_size;
2485 if ((got_frame = decoder_decode_frame(&is->auddec, is->frame, NULL)) < 0)
2488 if (is->auddec.flushed)
2489 is->audio_buf_frames_pending = 0;
2493 /* prepare a new audio buffer */
2494 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2496 VideoState *is = opaque;
2497 int audio_size, len1;
2499 audio_callback_time = av_gettime_relative();
2502 if (is->audio_buf_index >= is->audio_buf_size) {
2503 audio_size = audio_decode_frame(is);
2504 if (audio_size < 0) {
2505 /* if error, just output silence */
2506 is->audio_buf = is->silence_buf;
2507 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2509 if (is->show_mode != SHOW_MODE_VIDEO)
2510 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2511 is->audio_buf_size = audio_size;
2513 is->audio_buf_index = 0;
2515 len1 = is->audio_buf_size - is->audio_buf_index;
2518 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2521 is->audio_buf_index += len1;
2523 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2524 /* Let's assume the audio driver that is used by SDL has two periods. */
2525 if (!isnan(is->audio_clock)) {
2526 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);
2527 sync_clock_to_slave(&is->extclk, &is->audclk);
2531 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2533 SDL_AudioSpec wanted_spec, spec;
2535 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2536 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2537 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2539 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2541 wanted_nb_channels = atoi(env);
2542 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2544 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2545 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2546 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2548 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2549 wanted_spec.channels = wanted_nb_channels;
2550 wanted_spec.freq = wanted_sample_rate;
2551 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2552 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2555 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2556 next_sample_rate_idx--;
2557 wanted_spec.format = AUDIO_S16SYS;
2558 wanted_spec.silence = 0;
2559 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2560 wanted_spec.callback = sdl_audio_callback;
2561 wanted_spec.userdata = opaque;
2562 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2563 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2564 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2565 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2566 if (!wanted_spec.channels) {
2567 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2568 wanted_spec.channels = wanted_nb_channels;
2569 if (!wanted_spec.freq) {
2570 av_log(NULL, AV_LOG_ERROR,
2571 "No more combinations to try, audio open failed\n");
2575 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2577 if (spec.format != AUDIO_S16SYS) {
2578 av_log(NULL, AV_LOG_ERROR,
2579 "SDL advised audio format %d is not supported!\n", spec.format);
2582 if (spec.channels != wanted_spec.channels) {
2583 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2584 if (!wanted_channel_layout) {
2585 av_log(NULL, AV_LOG_ERROR,
2586 "SDL advised channel count %d is not supported!\n", spec.channels);
2591 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2592 audio_hw_params->freq = spec.freq;
2593 audio_hw_params->channel_layout = wanted_channel_layout;
2594 audio_hw_params->channels = spec.channels;
2595 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2596 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);
2597 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2598 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2604 /* open a given stream. Return 0 if OK */
2605 static int stream_component_open(VideoState *is, int stream_index)
2607 AVFormatContext *ic = is->ic;
2608 AVCodecContext *avctx;
2610 const char *forced_codec_name = NULL;
2612 AVDictionaryEntry *t = NULL;
2613 int sample_rate, nb_channels;
2614 int64_t channel_layout;
2616 int stream_lowres = lowres;
2618 if (stream_index < 0 || stream_index >= ic->nb_streams)
2620 avctx = ic->streams[stream_index]->codec;
2622 codec = avcodec_find_decoder(avctx->codec_id);
2624 switch(avctx->codec_type){
2625 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2626 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2627 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2629 if (forced_codec_name)
2630 codec = avcodec_find_decoder_by_name(forced_codec_name);
2632 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2633 "No codec could be found with name '%s'\n", forced_codec_name);
2634 else av_log(NULL, AV_LOG_WARNING,
2635 "No codec could be found with id %d\n", avctx->codec_id);
2639 avctx->codec_id = codec->id;
2640 avctx->workaround_bugs = workaround_bugs;
2641 if(stream_lowres > av_codec_get_max_lowres(codec)){
2642 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2643 av_codec_get_max_lowres(codec));
2644 stream_lowres = av_codec_get_max_lowres(codec);
2646 av_codec_set_lowres(avctx, stream_lowres);
2648 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2649 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2650 if(codec->capabilities & CODEC_CAP_DR1)
2651 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2653 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2654 if (!av_dict_get(opts, "threads", NULL, 0))
2655 av_dict_set(&opts, "threads", "auto", 0);
2657 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2658 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2659 av_dict_set(&opts, "refcounted_frames", "1", 0);
2660 if (avcodec_open2(avctx, codec, &opts) < 0)
2662 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2663 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2664 return AVERROR_OPTION_NOT_FOUND;
2667 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2668 switch (avctx->codec_type) {
2669 case AVMEDIA_TYPE_AUDIO:
2674 is->audio_filter_src.freq = avctx->sample_rate;
2675 is->audio_filter_src.channels = avctx->channels;
2676 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2677 is->audio_filter_src.fmt = avctx->sample_fmt;
2678 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2680 link = is->out_audio_filter->inputs[0];
2681 sample_rate = link->sample_rate;
2682 nb_channels = link->channels;
2683 channel_layout = link->channel_layout;
2686 sample_rate = avctx->sample_rate;
2687 nb_channels = avctx->channels;
2688 channel_layout = avctx->channel_layout;
2691 /* prepare audio output */
2692 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2694 is->audio_hw_buf_size = ret;
2695 is->audio_src = is->audio_tgt;
2696 is->audio_buf_size = 0;
2697 is->audio_buf_index = 0;
2699 /* init averaging filter */
2700 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2701 is->audio_diff_avg_count = 0;
2702 /* since we do not have a precise anough audio fifo fullness,
2703 we correct audio sync only if larger than this threshold */
2704 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2706 is->audio_stream = stream_index;
2707 is->audio_st = ic->streams[stream_index];
2709 packet_queue_start(&is->audioq);
2710 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2711 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2712 is->auddec.start_pts = is->audio_st->start_time;
2713 is->auddec.start_pts_tb = is->audio_st->time_base;
2717 case AVMEDIA_TYPE_VIDEO:
2718 is->video_stream = stream_index;
2719 is->video_st = ic->streams[stream_index];
2721 packet_queue_start(&is->videoq);
2722 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2723 is->video_tid = SDL_CreateThread(video_thread, is);
2724 is->queue_attachments_req = 1;
2726 case AVMEDIA_TYPE_SUBTITLE:
2727 is->subtitle_stream = stream_index;
2728 is->subtitle_st = ic->streams[stream_index];
2730 packet_queue_start(&is->subtitleq);
2731 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2732 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2740 static void stream_component_close(VideoState *is, int stream_index)
2742 AVFormatContext *ic = is->ic;
2743 AVCodecContext *avctx;
2745 if (stream_index < 0 || stream_index >= ic->nb_streams)
2747 avctx = ic->streams[stream_index]->codec;
2749 switch (avctx->codec_type) {
2750 case AVMEDIA_TYPE_AUDIO:
2751 packet_queue_abort(&is->audioq);
2755 decoder_destroy(&is->auddec);
2756 packet_queue_flush(&is->audioq);
2757 swr_free(&is->swr_ctx);
2758 av_freep(&is->audio_buf1);
2759 is->audio_buf1_size = 0;
2760 is->audio_buf = NULL;
2761 av_frame_free(&is->frame);
2764 av_rdft_end(is->rdft);
2765 av_freep(&is->rdft_data);
2770 avfilter_graph_free(&is->agraph);
2773 case AVMEDIA_TYPE_VIDEO:
2774 packet_queue_abort(&is->videoq);
2776 /* note: we also signal this mutex to make sure we deblock the
2777 video thread in all cases */
2778 frame_queue_signal(&is->pictq);
2780 SDL_WaitThread(is->video_tid, NULL);
2782 decoder_destroy(&is->viddec);
2783 packet_queue_flush(&is->videoq);
2785 case AVMEDIA_TYPE_SUBTITLE:
2786 packet_queue_abort(&is->subtitleq);
2788 /* note: we also signal this mutex to make sure we deblock the
2789 video thread in all cases */
2790 frame_queue_signal(&is->subpq);
2792 SDL_WaitThread(is->subtitle_tid, NULL);
2794 decoder_destroy(&is->subdec);
2795 packet_queue_flush(&is->subtitleq);
2801 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2802 avcodec_close(avctx);
2803 switch (avctx->codec_type) {
2804 case AVMEDIA_TYPE_AUDIO:
2805 is->audio_st = NULL;
2806 is->audio_stream = -1;
2808 case AVMEDIA_TYPE_VIDEO:
2809 is->video_st = NULL;
2810 is->video_stream = -1;
2812 case AVMEDIA_TYPE_SUBTITLE:
2813 is->subtitle_st = NULL;
2814 is->subtitle_stream = -1;
2821 static int decode_interrupt_cb(void *ctx)
2823 VideoState *is = ctx;
2824 return is->abort_request;
2827 static int is_realtime(AVFormatContext *s)
2829 if( !strcmp(s->iformat->name, "rtp")
2830 || !strcmp(s->iformat->name, "rtsp")
2831 || !strcmp(s->iformat->name, "sdp")
2835 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2836 || !strncmp(s->filename, "udp:", 4)
2843 /* this thread gets the stream from the disk or the network */
2844 static int read_thread(void *arg)
2846 VideoState *is = arg;
2847 AVFormatContext *ic = NULL;
2849 int st_index[AVMEDIA_TYPE_NB];
2850 AVPacket pkt1, *pkt = &pkt1;
2852 int64_t stream_start_time;
2853 int pkt_in_play_range = 0;
2854 AVDictionaryEntry *t;
2855 AVDictionary **opts;
2856 int orig_nb_streams;
2857 SDL_mutex *wait_mutex = SDL_CreateMutex();
2859 memset(st_index, -1, sizeof(st_index));
2860 is->last_video_stream = is->video_stream = -1;
2861 is->last_audio_stream = is->audio_stream = -1;
2862 is->last_subtitle_stream = is->subtitle_stream = -1;
2864 ic = avformat_alloc_context();
2865 ic->interrupt_callback.callback = decode_interrupt_cb;
2866 ic->interrupt_callback.opaque = is;
2867 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2869 print_error(is->filename, err);
2873 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2874 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2875 ret = AVERROR_OPTION_NOT_FOUND;
2881 ic->flags |= AVFMT_FLAG_GENPTS;
2883 av_format_inject_global_side_data(ic);
2885 opts = setup_find_stream_info_opts(ic, codec_opts);
2886 orig_nb_streams = ic->nb_streams;
2888 err = avformat_find_stream_info(ic, opts);
2890 av_log(NULL, AV_LOG_WARNING,
2891 "%s: could not find codec parameters\n", is->filename);
2895 for (i = 0; i < orig_nb_streams; i++)
2896 av_dict_free(&opts[i]);
2900 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2902 if (seek_by_bytes < 0)
2903 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2905 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2907 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2908 window_title = av_asprintf("%s - %s", t->value, input_filename);
2910 /* if seeking requested, we execute it */
2911 if (start_time != AV_NOPTS_VALUE) {
2914 timestamp = start_time;
2915 /* add the stream start time */
2916 if (ic->start_time != AV_NOPTS_VALUE)
2917 timestamp += ic->start_time;
2918 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2920 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2921 is->filename, (double)timestamp / AV_TIME_BASE);
2925 is->realtime = is_realtime(ic);
2927 for (i = 0; i < ic->nb_streams; i++)
2928 ic->streams[i]->discard = AVDISCARD_ALL;
2930 st_index[AVMEDIA_TYPE_VIDEO] =
2931 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2932 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2934 st_index[AVMEDIA_TYPE_AUDIO] =
2935 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2936 wanted_stream[AVMEDIA_TYPE_AUDIO],
2937 st_index[AVMEDIA_TYPE_VIDEO],
2939 if (!video_disable && !subtitle_disable)
2940 st_index[AVMEDIA_TYPE_SUBTITLE] =
2941 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2942 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2943 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2944 st_index[AVMEDIA_TYPE_AUDIO] :
2945 st_index[AVMEDIA_TYPE_VIDEO]),
2948 av_dump_format(ic, 0, is->filename, 0);
2951 is->show_mode = show_mode;
2952 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2953 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2954 AVCodecContext *avctx = st->codec;
2955 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2957 set_default_window_size(avctx->width, avctx->height, sar);
2960 /* open the streams */
2961 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2962 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2966 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2967 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2969 if (is->show_mode == SHOW_MODE_NONE)
2970 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2972 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2973 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2976 if (is->video_stream < 0 && is->audio_stream < 0) {
2977 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2983 if (infinite_buffer < 0 && is->realtime)
2984 infinite_buffer = 1;
2987 if (is->abort_request)
2989 if (is->paused != is->last_paused) {
2990 is->last_paused = is->paused;
2992 is->read_pause_return = av_read_pause(ic);
2996 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2998 (!strcmp(ic->iformat->name, "rtsp") ||
2999 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
3000 /* wait 10 ms to avoid trying to get another packet */
3007 int64_t seek_target = is->seek_pos;
3008 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3009 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3010 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3011 // of the seek_pos/seek_rel variables
3013 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3015 av_log(NULL, AV_LOG_ERROR,
3016 "%s: error while seeking\n", is->ic->filename);
3018 if (is->audio_stream >= 0) {
3019 packet_queue_flush(&is->audioq);
3020 packet_queue_put(&is->audioq, &flush_pkt);
3022 if (is->subtitle_stream >= 0) {
3023 packet_queue_flush(&is->subtitleq);
3024 packet_queue_put(&is->subtitleq, &flush_pkt);
3026 if (is->video_stream >= 0) {
3027 packet_queue_flush(&is->videoq);
3028 packet_queue_put(&is->videoq, &flush_pkt);
3030 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3031 set_clock(&is->extclk, NAN, 0);
3033 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3037 is->queue_attachments_req = 1;
3040 step_to_next_frame(is);
3042 if (is->queue_attachments_req) {
3043 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3045 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3047 packet_queue_put(&is->videoq, ©);
3048 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3050 is->queue_attachments_req = 0;
3053 /* if the queue are full, no need to read more */
3054 if (infinite_buffer<1 &&
3055 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3056 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3057 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3058 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3059 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3061 SDL_LockMutex(wait_mutex);
3062 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3063 SDL_UnlockMutex(wait_mutex);
3067 (!is->audio_st || is->auddec.finished == is->audioq.serial) &&
3068 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3069 if (loop != 1 && (!loop || --loop)) {
3070 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3071 } else if (autoexit) {
3077 if (is->video_stream >= 0)
3078 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3079 if (is->audio_stream >= 0)
3080 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3081 if (is->subtitle_stream >= 0)
3082 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3087 ret = av_read_frame(ic, pkt);
3089 if (ret == AVERROR_EOF || avio_feof(ic->pb))
3091 if (ic->pb && ic->pb->error)
3093 SDL_LockMutex(wait_mutex);
3094 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3095 SDL_UnlockMutex(wait_mutex);
3098 /* check if packet is in play range specified by user, then queue, otherwise discard */
3099 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3100 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3101 (pkt->pts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3102 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3103 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3104 <= ((double)duration / 1000000);
3105 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3106 packet_queue_put(&is->audioq, pkt);
3107 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3108 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3109 packet_queue_put(&is->videoq, pkt);
3110 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3111 packet_queue_put(&is->subtitleq, pkt);
3113 av_free_packet(pkt);
3116 /* wait until the end */
3117 while (!is->abort_request) {
3123 /* close each stream */
3124 if (is->audio_stream >= 0)
3125 stream_component_close(is, is->audio_stream);
3126 if (is->video_stream >= 0)
3127 stream_component_close(is, is->video_stream);
3128 if (is->subtitle_stream >= 0)
3129 stream_component_close(is, is->subtitle_stream);
3131 avformat_close_input(&is->ic);
3137 event.type = FF_QUIT_EVENT;
3138 event.user.data1 = is;
3139 SDL_PushEvent(&event);
3141 SDL_DestroyMutex(wait_mutex);
3145 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3149 is = av_mallocz(sizeof(VideoState));
3152 av_strlcpy(is->filename, filename, sizeof(is->filename));
3153 is->iformat = iformat;
3157 /* start video display */
3158 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3160 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3163 packet_queue_init(&is->videoq);
3164 packet_queue_init(&is->audioq);
3165 packet_queue_init(&is->subtitleq);
3167 is->continue_read_thread = SDL_CreateCond();
3169 init_clock(&is->vidclk, &is->videoq.serial);
3170 init_clock(&is->audclk, &is->audioq.serial);
3171 init_clock(&is->extclk, &is->extclk.serial);
3172 is->audio_clock_serial = -1;
3173 is->audio_last_serial = -1;
3174 is->av_sync_type = av_sync_type;
3175 is->read_tid = SDL_CreateThread(read_thread, is);
3176 if (!is->read_tid) {
3184 static void stream_cycle_channel(VideoState *is, int codec_type)
3186 AVFormatContext *ic = is->ic;
3187 int start_index, stream_index;
3190 AVProgram *p = NULL;
3191 int nb_streams = is->ic->nb_streams;
3193 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3194 start_index = is->last_video_stream;
3195 old_index = is->video_stream;
3196 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3197 start_index = is->last_audio_stream;
3198 old_index = is->audio_stream;
3200 start_index = is->last_subtitle_stream;
3201 old_index = is->subtitle_stream;
3203 stream_index = start_index;
3205 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3206 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3208 nb_streams = p->nb_stream_indexes;
3209 for (start_index = 0; start_index < nb_streams; start_index++)
3210 if (p->stream_index[start_index] == stream_index)
3212 if (start_index == nb_streams)
3214 stream_index = start_index;
3219 if (++stream_index >= nb_streams)
3221 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3224 is->last_subtitle_stream = -1;
3227 if (start_index == -1)
3231 if (stream_index == start_index)
3233 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3234 if (st->codec->codec_type == codec_type) {
3235 /* check that parameters are OK */
3236 switch (codec_type) {
3237 case AVMEDIA_TYPE_AUDIO:
3238 if (st->codec->sample_rate != 0 &&
3239 st->codec->channels != 0)
3242 case AVMEDIA_TYPE_VIDEO:
3243 case AVMEDIA_TYPE_SUBTITLE:
3251 if (p && stream_index != -1)
3252 stream_index = p->stream_index[stream_index];
3253 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3254 av_get_media_type_string(codec_type),
3258 stream_component_close(is, old_index);
3259 stream_component_open(is, stream_index);
3263 static void toggle_full_screen(VideoState *is)
3265 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3266 /* OS X needs to reallocate the SDL overlays */
3268 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3269 is->pictq.queue[i].reallocate = 1;
3271 is_full_screen = !is_full_screen;
3272 video_open(is, 1, NULL);
3275 static void toggle_audio_display(VideoState *is)
3277 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3278 int next = is->show_mode;
3280 next = (next + 1) % SHOW_MODE_NB;
3281 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3282 if (is->show_mode != next) {
3283 fill_rectangle(screen,
3284 is->xleft, is->ytop, is->width, is->height,
3286 is->force_refresh = 1;
3287 is->show_mode = next;
3291 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3292 double remaining_time = 0.0;
3294 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3295 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3299 if (remaining_time > 0.0)
3300 av_usleep((int64_t)(remaining_time * 1000000.0));
3301 remaining_time = REFRESH_RATE;
3302 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3303 video_refresh(is, &remaining_time);
3308 static void seek_chapter(VideoState *is, int incr)
3310 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3313 if (!is->ic->nb_chapters)
3316 /* find the current chapter */
3317 for (i = 0; i < is->ic->nb_chapters; i++) {
3318 AVChapter *ch = is->ic->chapters[i];
3319 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3327 if (i >= is->ic->nb_chapters)
3330 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3331 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3332 AV_TIME_BASE_Q), 0, 0);
3335 /* handle an event sent by the GUI */
3336 static void event_loop(VideoState *cur_stream)
3339 double incr, pos, frac;
3343 refresh_loop_wait_event(cur_stream, &event);
3344 switch (event.type) {
3346 if (exit_on_keydown) {
3347 do_exit(cur_stream);
3350 switch (event.key.keysym.sym) {
3353 do_exit(cur_stream);
3356 toggle_full_screen(cur_stream);
3357 cur_stream->force_refresh = 1;
3361 toggle_pause(cur_stream);
3363 case SDLK_s: // S: Step to next frame
3364 step_to_next_frame(cur_stream);
3367 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3370 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3373 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3374 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3375 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3378 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3382 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3383 if (++cur_stream->vfilter_idx >= nb_vfilters)
3384 cur_stream->vfilter_idx = 0;
3386 cur_stream->vfilter_idx = 0;
3387 toggle_audio_display(cur_stream);
3390 toggle_audio_display(cur_stream);
3394 if (cur_stream->ic->nb_chapters <= 1) {
3398 seek_chapter(cur_stream, 1);
3401 if (cur_stream->ic->nb_chapters <= 1) {
3405 seek_chapter(cur_stream, -1);
3419 if (seek_by_bytes) {
3421 if (pos < 0 && cur_stream->video_stream >= 0)
3422 pos = frame_queue_last_pos(&cur_stream->pictq);
3423 if (pos < 0 && cur_stream->audio_stream >= 0 && cur_stream->frame)
3424 pos = av_frame_get_pkt_pos(cur_stream->frame);
3426 pos = avio_tell(cur_stream->ic->pb);
3427 if (cur_stream->ic->bit_rate)
3428 incr *= cur_stream->ic->bit_rate / 8.0;
3432 stream_seek(cur_stream, pos, incr, 1);
3434 pos = get_master_clock(cur_stream);
3436 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3438 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3439 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3440 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3447 case SDL_VIDEOEXPOSE:
3448 cur_stream->force_refresh = 1;
3450 case SDL_MOUSEBUTTONDOWN:
3451 if (exit_on_mousedown) {
3452 do_exit(cur_stream);
3455 case SDL_MOUSEMOTION:
3456 if (cursor_hidden) {
3460 cursor_last_shown = av_gettime_relative();
3461 if (event.type == SDL_MOUSEBUTTONDOWN) {
3464 if (event.motion.state != SDL_PRESSED)
3468 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3469 uint64_t size = avio_size(cur_stream->ic->pb);
3470 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3474 int tns, thh, tmm, tss;
3475 tns = cur_stream->ic->duration / 1000000LL;
3477 tmm = (tns % 3600) / 60;
3479 frac = x / cur_stream->width;
3482 mm = (ns % 3600) / 60;
3484 av_log(NULL, AV_LOG_INFO,
3485 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3486 hh, mm, ss, thh, tmm, tss);
3487 ts = frac * cur_stream->ic->duration;
3488 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3489 ts += cur_stream->ic->start_time;
3490 stream_seek(cur_stream, ts, 0, 0);
3493 case SDL_VIDEORESIZE:
3494 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3495 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3497 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3498 do_exit(cur_stream);
3500 screen_width = cur_stream->width = screen->w;
3501 screen_height = cur_stream->height = screen->h;
3502 cur_stream->force_refresh = 1;
3506 do_exit(cur_stream);
3508 case FF_ALLOC_EVENT:
3509 alloc_picture(event.user.data1);
3517 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3519 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3520 return opt_default(NULL, "video_size", arg);
3523 static int opt_width(void *optctx, const char *opt, const char *arg)
3525 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3529 static int opt_height(void *optctx, const char *opt, const char *arg)
3531 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3535 static int opt_format(void *optctx, const char *opt, const char *arg)
3537 file_iformat = av_find_input_format(arg);
3538 if (!file_iformat) {
3539 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3540 return AVERROR(EINVAL);
3545 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3547 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3548 return opt_default(NULL, "pixel_format", arg);
3551 static int opt_sync(void *optctx, const char *opt, const char *arg)
3553 if (!strcmp(arg, "audio"))
3554 av_sync_type = AV_SYNC_AUDIO_MASTER;
3555 else if (!strcmp(arg, "video"))
3556 av_sync_type = AV_SYNC_VIDEO_MASTER;
3557 else if (!strcmp(arg, "ext"))
3558 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3560 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3566 static int opt_seek(void *optctx, const char *opt, const char *arg)
3568 start_time = parse_time_or_die(opt, arg, 1);
3572 static int opt_duration(void *optctx, const char *opt, const char *arg)
3574 duration = parse_time_or_die(opt, arg, 1);
3578 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3580 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3581 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3582 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3583 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3587 static void opt_input_file(void *optctx, const char *filename)
3589 if (input_filename) {
3590 av_log(NULL, AV_LOG_FATAL,
3591 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3592 filename, input_filename);
3595 if (!strcmp(filename, "-"))
3597 input_filename = filename;
3600 static int opt_codec(void *optctx, const char *opt, const char *arg)
3602 const char *spec = strchr(opt, ':');
3604 av_log(NULL, AV_LOG_ERROR,
3605 "No media specifier was specified in '%s' in option '%s'\n",
3607 return AVERROR(EINVAL);
3611 case 'a' : audio_codec_name = arg; break;
3612 case 's' : subtitle_codec_name = arg; break;
3613 case 'v' : video_codec_name = arg; break;
3615 av_log(NULL, AV_LOG_ERROR,
3616 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3617 return AVERROR(EINVAL);
3624 static const OptionDef options[] = {
3625 #include "cmdutils_common_opts.h"
3626 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3627 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3628 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3629 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3630 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3631 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3632 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3633 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3634 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3635 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3636 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3637 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3638 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3639 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3640 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3641 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3642 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3643 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
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");