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 VideoState {
181 SDL_Thread *read_tid;
182 SDL_Thread *video_tid;
183 AVInputFormat *iformat;
189 int queue_attachments_req;
194 int read_pause_return;
212 int audio_clock_serial;
213 double audio_diff_cum; /* used for AV difference average computation */
214 double audio_diff_avg_coef;
215 double audio_diff_threshold;
216 int audio_diff_avg_count;
219 int audio_hw_buf_size;
220 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
223 unsigned int audio_buf_size; /* in bytes */
224 unsigned int audio_buf1_size;
225 int audio_buf_index; /* in bytes */
226 int audio_write_buf_size;
227 int audio_buf_frames_pending;
228 AVPacket audio_pkt_temp;
230 int audio_pkt_temp_serial;
231 int audio_last_serial;
232 struct AudioParams audio_src;
234 struct AudioParams audio_filter_src;
236 struct AudioParams audio_tgt;
237 struct SwrContext *swr_ctx;
238 int frame_drops_early;
239 int frame_drops_late;
241 int64_t audio_frame_next_pts;
244 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
246 int16_t sample_array[SAMPLE_ARRAY_SIZE];
247 int sample_array_index;
251 FFTSample *rdft_data;
253 double last_vis_time;
255 SDL_Thread *subtitle_tid;
257 AVStream *subtitle_st;
258 PacketQueue subtitleq;
261 double frame_last_returned_time;
262 double frame_last_filter_delay;
266 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
268 struct SwsContext *img_convert_ctx;
270 SDL_Rect last_display_rect;
273 int width, height, xleft, ytop;
278 AVFilterContext *in_video_filter; // the first filter in the video chain
279 AVFilterContext *out_video_filter; // the last filter in the video chain
280 AVFilterContext *in_audio_filter; // the first filter in the audio chain
281 AVFilterContext *out_audio_filter; // the last filter in the audio chain
282 AVFilterGraph *agraph; // audio filter graph
285 int last_video_stream, last_audio_stream, last_subtitle_stream;
287 SDL_cond *continue_read_thread;
290 /* options specified by the user */
291 static AVInputFormat *file_iformat;
292 static const char *input_filename;
293 static const char *window_title;
294 static int fs_screen_width;
295 static int fs_screen_height;
296 static int default_width = 640;
297 static int default_height = 480;
298 static int screen_width = 0;
299 static int screen_height = 0;
300 static int audio_disable;
301 static int video_disable;
302 static int subtitle_disable;
303 static int wanted_stream[AVMEDIA_TYPE_NB] = {
304 [AVMEDIA_TYPE_AUDIO] = -1,
305 [AVMEDIA_TYPE_VIDEO] = -1,
306 [AVMEDIA_TYPE_SUBTITLE] = -1,
308 static int seek_by_bytes = -1;
309 static int display_disable;
310 static int show_status = 1;
311 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
312 static int64_t start_time = AV_NOPTS_VALUE;
313 static int64_t duration = AV_NOPTS_VALUE;
314 static int workaround_bugs = 1;
316 static int genpts = 0;
317 static int lowres = 0;
318 static int decoder_reorder_pts = -1;
320 static int exit_on_keydown;
321 static int exit_on_mousedown;
323 static int framedrop = -1;
324 static int infinite_buffer = -1;
325 static enum ShowMode show_mode = SHOW_MODE_NONE;
326 static const char *audio_codec_name;
327 static const char *subtitle_codec_name;
328 static const char *video_codec_name;
329 double rdftspeed = 0.02;
330 static int64_t cursor_last_shown;
331 static int cursor_hidden = 0;
333 static const char **vfilters_list = NULL;
334 static int nb_vfilters = 0;
335 static char *afilters = NULL;
337 static int autorotate = 1;
339 /* current context */
340 static int is_full_screen;
341 static int64_t audio_callback_time;
343 static AVPacket flush_pkt;
345 #define FF_ALLOC_EVENT (SDL_USEREVENT)
346 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
348 static SDL_Surface *screen;
351 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
353 GROW_ARRAY(vfilters_list, nb_vfilters);
354 vfilters_list[nb_vfilters - 1] = arg;
360 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
361 enum AVSampleFormat fmt2, int64_t channel_count2)
363 /* If channel count == 1, planar and non-planar formats are the same */
364 if (channel_count1 == 1 && channel_count2 == 1)
365 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
367 return channel_count1 != channel_count2 || fmt1 != fmt2;
371 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
373 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
374 return channel_layout;
379 static void free_picture(Frame *vp);
381 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
383 MyAVPacketList *pkt1;
385 if (q->abort_request)
388 pkt1 = av_malloc(sizeof(MyAVPacketList));
393 if (pkt == &flush_pkt)
395 pkt1->serial = q->serial;
400 q->last_pkt->next = pkt1;
403 q->size += pkt1->pkt.size + sizeof(*pkt1);
404 /* XXX: should duplicate packet data in DV case */
405 SDL_CondSignal(q->cond);
409 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
413 /* duplicate the packet */
414 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
417 SDL_LockMutex(q->mutex);
418 ret = packet_queue_put_private(q, pkt);
419 SDL_UnlockMutex(q->mutex);
421 if (pkt != &flush_pkt && ret < 0)
427 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
429 AVPacket pkt1, *pkt = &pkt1;
433 pkt->stream_index = stream_index;
434 return packet_queue_put(q, pkt);
437 /* packet queue handling */
438 static void packet_queue_init(PacketQueue *q)
440 memset(q, 0, sizeof(PacketQueue));
441 q->mutex = SDL_CreateMutex();
442 q->cond = SDL_CreateCond();
443 q->abort_request = 1;
446 static void packet_queue_flush(PacketQueue *q)
448 MyAVPacketList *pkt, *pkt1;
450 SDL_LockMutex(q->mutex);
451 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
453 av_free_packet(&pkt->pkt);
460 SDL_UnlockMutex(q->mutex);
463 static void packet_queue_destroy(PacketQueue *q)
465 packet_queue_flush(q);
466 SDL_DestroyMutex(q->mutex);
467 SDL_DestroyCond(q->cond);
470 static void packet_queue_abort(PacketQueue *q)
472 SDL_LockMutex(q->mutex);
474 q->abort_request = 1;
476 SDL_CondSignal(q->cond);
478 SDL_UnlockMutex(q->mutex);
481 static void packet_queue_start(PacketQueue *q)
483 SDL_LockMutex(q->mutex);
484 q->abort_request = 0;
485 packet_queue_put_private(q, &flush_pkt);
486 SDL_UnlockMutex(q->mutex);
489 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
490 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
492 MyAVPacketList *pkt1;
495 SDL_LockMutex(q->mutex);
498 if (q->abort_request) {
505 q->first_pkt = pkt1->next;
509 q->size -= pkt1->pkt.size + sizeof(*pkt1);
512 *serial = pkt1->serial;
520 SDL_CondWait(q->cond, q->mutex);
523 SDL_UnlockMutex(q->mutex);
527 static void frame_queue_unref_item(Frame *vp)
529 av_frame_unref(vp->frame);
530 avsubtitle_free(&vp->sub);
533 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
536 memset(f, 0, sizeof(FrameQueue));
537 if (!(f->mutex = SDL_CreateMutex()))
538 return AVERROR(ENOMEM);
539 if (!(f->cond = SDL_CreateCond()))
540 return AVERROR(ENOMEM);
542 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
543 f->keep_last = !!keep_last;
544 for (i = 0; i < f->max_size; i++)
545 if (!(f->queue[i].frame = av_frame_alloc()))
546 return AVERROR(ENOMEM);
550 static void frame_queue_destory(FrameQueue *f)
553 for (i = 0; i < f->max_size; i++) {
554 Frame *vp = &f->queue[i];
555 frame_queue_unref_item(vp);
556 av_frame_free(&vp->frame);
559 SDL_DestroyMutex(f->mutex);
560 SDL_DestroyCond(f->cond);
563 static void frame_queue_signal(FrameQueue *f)
565 SDL_LockMutex(f->mutex);
566 SDL_CondSignal(f->cond);
567 SDL_UnlockMutex(f->mutex);
570 static Frame *frame_queue_peek(FrameQueue *f)
572 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
575 static Frame *frame_queue_peek_next(FrameQueue *f)
577 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
580 static Frame *frame_queue_peek_last(FrameQueue *f)
582 return &f->queue[f->rindex];
585 static Frame *frame_queue_peek_writable(FrameQueue *f)
587 /* wait until we have space to put a new frame */
588 SDL_LockMutex(f->mutex);
589 while (f->size >= f->max_size &&
590 !f->pktq->abort_request) {
591 SDL_CondWait(f->cond, f->mutex);
593 SDL_UnlockMutex(f->mutex);
595 if (f->pktq->abort_request)
598 return &f->queue[f->windex];
601 static void frame_queue_push(FrameQueue *f)
603 if (++f->windex == f->max_size)
605 SDL_LockMutex(f->mutex);
607 SDL_UnlockMutex(f->mutex);
610 static void frame_queue_next(FrameQueue *f)
612 if (f->keep_last && !f->rindex_shown) {
616 frame_queue_unref_item(&f->queue[f->rindex]);
617 if (++f->rindex == f->max_size)
619 SDL_LockMutex(f->mutex);
621 SDL_CondSignal(f->cond);
622 SDL_UnlockMutex(f->mutex);
625 /* jump back to the previous frame if available by resetting rindex_shown */
626 static int frame_queue_prev(FrameQueue *f)
628 int ret = f->rindex_shown;
633 /* return the number of undisplayed frames in the queue */
634 static int frame_queue_nb_remaining(FrameQueue *f)
636 return f->size - f->rindex_shown;
639 /* return last shown position */
640 static int64_t frame_queue_last_pos(FrameQueue *f)
642 Frame *fp = &f->queue[f->rindex];
643 if (f->rindex_shown && fp->serial == f->pktq->serial)
649 static inline void fill_rectangle(SDL_Surface *screen,
650 int x, int y, int w, int h, int color, int update)
657 SDL_FillRect(screen, &rect, color);
658 if (update && w > 0 && h > 0)
659 SDL_UpdateRect(screen, x, y, w, h);
662 /* draw only the border of a rectangle */
663 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
667 /* fill the background */
671 w2 = width - (x + w);
677 h2 = height - (y + h);
680 fill_rectangle(screen,
684 fill_rectangle(screen,
685 xleft + width - w2, ytop,
688 fill_rectangle(screen,
692 fill_rectangle(screen,
693 xleft + w1, ytop + height - h2,
698 #define ALPHA_BLEND(a, oldp, newp, s)\
699 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
701 #define RGBA_IN(r, g, b, a, s)\
703 unsigned int v = ((const uint32_t *)(s))[0];\
704 a = (v >> 24) & 0xff;\
705 r = (v >> 16) & 0xff;\
706 g = (v >> 8) & 0xff;\
710 #define YUVA_IN(y, u, v, a, s, pal)\
712 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
713 a = (val >> 24) & 0xff;\
714 y = (val >> 16) & 0xff;\
715 u = (val >> 8) & 0xff;\
719 #define YUVA_OUT(d, y, u, v, a)\
721 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
727 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
729 int wrap, wrap3, width2, skip2;
730 int y, u, v, a, u1, v1, a1, w, h;
731 uint8_t *lum, *cb, *cr;
734 int dstx, dsty, dstw, dsth;
736 dstw = av_clip(rect->w, 0, imgw);
737 dsth = av_clip(rect->h, 0, imgh);
738 dstx = av_clip(rect->x, 0, imgw - dstw);
739 dsty = av_clip(rect->y, 0, imgh - dsth);
740 lum = dst->data[0] + dsty * dst->linesize[0];
741 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
742 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
744 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
746 wrap = dst->linesize[0];
747 wrap3 = rect->pict.linesize[0];
748 p = rect->pict.data[0];
749 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
757 YUVA_IN(y, u, v, a, p, pal);
758 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
759 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
760 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
766 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
767 YUVA_IN(y, u, v, a, p, pal);
771 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
773 YUVA_IN(y, u, v, a, p + BPP, pal);
777 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
778 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
779 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
786 YUVA_IN(y, u, v, a, p, pal);
787 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
788 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
789 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
793 p += wrap3 - dstw * BPP;
794 lum += wrap - dstw - dstx;
795 cb += dst->linesize[1] - width2 - skip2;
796 cr += dst->linesize[2] - width2 - skip2;
798 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
804 YUVA_IN(y, u, v, a, p, pal);
808 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
811 YUVA_IN(y, u, v, a, p, pal);
815 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
816 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
817 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
823 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
824 YUVA_IN(y, u, v, a, p, pal);
828 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
830 YUVA_IN(y, u, v, a, p + BPP, pal);
834 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
838 YUVA_IN(y, u, v, a, p, pal);
842 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
844 YUVA_IN(y, u, v, a, p + BPP, pal);
848 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
850 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
851 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
855 p += -wrap3 + 2 * BPP;
859 YUVA_IN(y, u, v, a, p, pal);
863 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
866 YUVA_IN(y, u, v, a, p, pal);
870 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
871 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
872 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
878 p += wrap3 + (wrap3 - dstw * BPP);
879 lum += wrap + (wrap - dstw - dstx);
880 cb += dst->linesize[1] - width2 - skip2;
881 cr += dst->linesize[2] - width2 - skip2;
883 /* handle odd height */
890 YUVA_IN(y, u, v, a, p, pal);
891 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
892 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
893 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
899 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
900 YUVA_IN(y, u, v, a, p, pal);
904 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
906 YUVA_IN(y, u, v, a, p + BPP, pal);
910 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
911 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
912 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
919 YUVA_IN(y, u, v, a, p, pal);
920 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
921 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
922 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
927 static void free_picture(Frame *vp)
930 SDL_FreeYUVOverlay(vp->bmp);
935 static void calculate_display_rect(SDL_Rect *rect,
936 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
937 int pic_width, int pic_height, AVRational pic_sar)
940 int width, height, x, y;
942 if (pic_sar.num == 0)
945 aspect_ratio = av_q2d(pic_sar);
947 if (aspect_ratio <= 0.0)
949 aspect_ratio *= (float)pic_width / (float)pic_height;
951 /* XXX: we suppose the screen has a 1.0 pixel ratio */
953 width = ((int)rint(height * aspect_ratio)) & ~1;
954 if (width > scr_width) {
956 height = ((int)rint(width / aspect_ratio)) & ~1;
958 x = (scr_width - width) / 2;
959 y = (scr_height - height) / 2;
960 rect->x = scr_xleft + x;
961 rect->y = scr_ytop + y;
962 rect->w = FFMAX(width, 1);
963 rect->h = FFMAX(height, 1);
966 static void video_image_display(VideoState *is)
974 vp = frame_queue_peek(&is->pictq);
976 if (is->subtitle_st) {
977 if (frame_queue_nb_remaining(&is->subpq) > 0) {
978 sp = frame_queue_peek(&is->subpq);
980 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
981 SDL_LockYUVOverlay (vp->bmp);
983 pict.data[0] = vp->bmp->pixels[0];
984 pict.data[1] = vp->bmp->pixels[2];
985 pict.data[2] = vp->bmp->pixels[1];
987 pict.linesize[0] = vp->bmp->pitches[0];
988 pict.linesize[1] = vp->bmp->pitches[2];
989 pict.linesize[2] = vp->bmp->pitches[1];
991 for (i = 0; i < sp->sub.num_rects; i++)
992 blend_subrect(&pict, sp->sub.rects[i],
993 vp->bmp->w, vp->bmp->h);
995 SDL_UnlockYUVOverlay (vp->bmp);
1000 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
1002 SDL_DisplayYUVOverlay(vp->bmp, &rect);
1004 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) {
1005 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1006 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
1007 is->last_display_rect = rect;
1012 static inline int compute_mod(int a, int b)
1014 return a < 0 ? a%b + b : a%b;
1017 static void video_audio_display(VideoState *s)
1019 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1020 int ch, channels, h, h2, bgcolor, fgcolor;
1022 int rdft_bits, nb_freq;
1024 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
1026 nb_freq = 1 << (rdft_bits - 1);
1028 /* compute display index : center on currently output samples */
1029 channels = s->audio_tgt.channels;
1030 nb_display_channels = channels;
1032 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1034 delay = s->audio_write_buf_size;
1037 /* to be more precise, we take into account the time spent since
1038 the last buffer computation */
1039 if (audio_callback_time) {
1040 time_diff = av_gettime_relative() - audio_callback_time;
1041 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1044 delay += 2 * data_used;
1045 if (delay < data_used)
1048 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1049 if (s->show_mode == SHOW_MODE_WAVES) {
1051 for (i = 0; i < 1000; i += channels) {
1052 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1053 int a = s->sample_array[idx];
1054 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1055 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1056 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1058 if (h < score && (b ^ c) < 0) {
1065 s->last_i_start = i_start;
1067 i_start = s->last_i_start;
1070 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1071 if (s->show_mode == SHOW_MODE_WAVES) {
1072 fill_rectangle(screen,
1073 s->xleft, s->ytop, s->width, s->height,
1076 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1078 /* total height for one channel */
1079 h = s->height / nb_display_channels;
1080 /* graph height / 2 */
1082 for (ch = 0; ch < nb_display_channels; ch++) {
1084 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1085 for (x = 0; x < s->width; x++) {
1086 y = (s->sample_array[i] * h2) >> 15;
1093 fill_rectangle(screen,
1094 s->xleft + x, ys, 1, y,
1097 if (i >= SAMPLE_ARRAY_SIZE)
1098 i -= SAMPLE_ARRAY_SIZE;
1102 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1104 for (ch = 1; ch < nb_display_channels; ch++) {
1105 y = s->ytop + ch * h;
1106 fill_rectangle(screen,
1107 s->xleft, y, s->width, 1,
1110 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1112 nb_display_channels= FFMIN(nb_display_channels, 2);
1113 if (rdft_bits != s->rdft_bits) {
1114 av_rdft_end(s->rdft);
1115 av_free(s->rdft_data);
1116 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1117 s->rdft_bits = rdft_bits;
1118 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1122 for (ch = 0; ch < nb_display_channels; ch++) {
1123 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1125 for (x = 0; x < 2 * nb_freq; x++) {
1126 double w = (x-nb_freq) * (1.0 / nb_freq);
1127 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1129 if (i >= SAMPLE_ARRAY_SIZE)
1130 i -= SAMPLE_ARRAY_SIZE;
1132 av_rdft_calc(s->rdft, data[ch]);
1134 /* Least efficient way to do this, we should of course
1135 * directly access it but it is more than fast enough. */
1136 for (y = 0; y < s->height; y++) {
1137 double w = 1 / sqrt(nb_freq);
1138 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]));
1139 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1140 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1143 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1145 fill_rectangle(screen,
1146 s->xpos, s->height-y, 1, 1,
1150 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1153 if (s->xpos >= s->width)
1158 static void stream_close(VideoState *is)
1160 /* XXX: use a special url_shutdown call to abort parse cleanly */
1161 is->abort_request = 1;
1162 SDL_WaitThread(is->read_tid, NULL);
1163 packet_queue_destroy(&is->videoq);
1164 packet_queue_destroy(&is->audioq);
1165 packet_queue_destroy(&is->subtitleq);
1167 /* free all pictures */
1168 frame_queue_destory(&is->pictq);
1169 frame_queue_destory(&is->subpq);
1170 SDL_DestroyCond(is->continue_read_thread);
1171 #if !CONFIG_AVFILTER
1172 sws_freeContext(is->img_convert_ctx);
1177 static void do_exit(VideoState *is)
1182 av_lockmgr_register(NULL);
1185 av_freep(&vfilters_list);
1187 avformat_network_deinit();
1191 av_log(NULL, AV_LOG_QUIET, "%s", "");
1195 static void sigterm_handler(int sig)
1200 static void set_default_window_size(int width, int height, AVRational sar)
1203 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1204 default_width = rect.w;
1205 default_height = rect.h;
1208 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1210 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1213 if (is_full_screen) flags |= SDL_FULLSCREEN;
1214 else flags |= SDL_RESIZABLE;
1216 if (vp && vp->width)
1217 set_default_window_size(vp->width, vp->height, vp->sar);
1219 if (is_full_screen && fs_screen_width) {
1220 w = fs_screen_width;
1221 h = fs_screen_height;
1222 } else if (!is_full_screen && screen_width) {
1229 w = FFMIN(16383, w);
1230 if (screen && is->width == screen->w && screen->w == w
1231 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1233 screen = SDL_SetVideoMode(w, h, 0, flags);
1235 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1239 window_title = input_filename;
1240 SDL_WM_SetCaption(window_title, window_title);
1242 is->width = screen->w;
1243 is->height = screen->h;
1248 /* display the current picture, if any */
1249 static void video_display(VideoState *is)
1252 video_open(is, 0, NULL);
1253 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1254 video_audio_display(is);
1255 else if (is->video_st)
1256 video_image_display(is);
1259 static double get_clock(Clock *c)
1261 if (*c->queue_serial != c->serial)
1266 double time = av_gettime_relative() / 1000000.0;
1267 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1271 static void set_clock_at(Clock *c, double pts, int serial, double time)
1274 c->last_updated = time;
1275 c->pts_drift = c->pts - time;
1279 static void set_clock(Clock *c, double pts, int serial)
1281 double time = av_gettime_relative() / 1000000.0;
1282 set_clock_at(c, pts, serial, time);
1285 static void set_clock_speed(Clock *c, double speed)
1287 set_clock(c, get_clock(c), c->serial);
1291 static void init_clock(Clock *c, int *queue_serial)
1295 c->queue_serial = queue_serial;
1296 set_clock(c, NAN, -1);
1299 static void sync_clock_to_slave(Clock *c, Clock *slave)
1301 double clock = get_clock(c);
1302 double slave_clock = get_clock(slave);
1303 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1304 set_clock(c, slave_clock, slave->serial);
1307 static int get_master_sync_type(VideoState *is) {
1308 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1310 return AV_SYNC_VIDEO_MASTER;
1312 return AV_SYNC_AUDIO_MASTER;
1313 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1315 return AV_SYNC_AUDIO_MASTER;
1317 return AV_SYNC_EXTERNAL_CLOCK;
1319 return AV_SYNC_EXTERNAL_CLOCK;
1323 /* get the current master clock value */
1324 static double get_master_clock(VideoState *is)
1328 switch (get_master_sync_type(is)) {
1329 case AV_SYNC_VIDEO_MASTER:
1330 val = get_clock(&is->vidclk);
1332 case AV_SYNC_AUDIO_MASTER:
1333 val = get_clock(&is->audclk);
1336 val = get_clock(&is->extclk);
1342 static void check_external_clock_speed(VideoState *is) {
1343 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1344 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1345 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1346 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1347 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1348 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1350 double speed = is->extclk.speed;
1352 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1356 /* seek in the stream */
1357 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1359 if (!is->seek_req) {
1362 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1364 is->seek_flags |= AVSEEK_FLAG_BYTE;
1366 SDL_CondSignal(is->continue_read_thread);
1370 /* pause or resume the video */
1371 static void stream_toggle_pause(VideoState *is)
1374 is->frame_timer += av_gettime_relative() / 1000000.0 + is->vidclk.pts_drift - is->vidclk.pts;
1375 if (is->read_pause_return != AVERROR(ENOSYS)) {
1376 is->vidclk.paused = 0;
1378 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1380 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1381 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1384 static void toggle_pause(VideoState *is)
1386 stream_toggle_pause(is);
1390 static void step_to_next_frame(VideoState *is)
1392 /* if the stream is paused unpause it, then step */
1394 stream_toggle_pause(is);
1398 static double compute_target_delay(double delay, VideoState *is)
1400 double sync_threshold, diff;
1402 /* update delay to follow master synchronisation source */
1403 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1404 /* if video is slave, we try to correct big delays by
1405 duplicating or deleting a frame */
1406 diff = get_clock(&is->vidclk) - get_master_clock(is);
1408 /* skip or repeat frame. We take into account the
1409 delay to compute the threshold. I still don't know
1410 if it is the best guess */
1411 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1412 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1413 if (diff <= -sync_threshold)
1414 delay = FFMAX(0, delay + diff);
1415 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1416 delay = delay + diff;
1417 else if (diff >= sync_threshold)
1422 av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1428 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1429 if (vp->serial == nextvp->serial) {
1430 double duration = nextvp->pts - vp->pts;
1431 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1432 return vp->duration;
1440 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1441 /* update current video pts */
1442 set_clock(&is->vidclk, pts, serial);
1443 sync_clock_to_slave(&is->extclk, &is->vidclk);
1446 /* called to display each frame */
1447 static void video_refresh(void *opaque, double *remaining_time)
1449 VideoState *is = opaque;
1454 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1455 check_external_clock_speed(is);
1457 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1458 time = av_gettime_relative() / 1000000.0;
1459 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1461 is->last_vis_time = time;
1463 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1468 if (is->force_refresh)
1469 redisplay = frame_queue_prev(&is->pictq);
1471 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1472 // nothing to do, no picture to display in the queue
1474 double last_duration, duration, delay;
1477 /* dequeue the picture */
1478 lastvp = frame_queue_peek_last(&is->pictq);
1479 vp = frame_queue_peek(&is->pictq);
1481 if (vp->serial != is->videoq.serial) {
1482 frame_queue_next(&is->pictq);
1487 if (lastvp->serial != vp->serial && !redisplay)
1488 is->frame_timer = av_gettime_relative() / 1000000.0;
1493 /* compute nominal last_duration */
1494 last_duration = vp_duration(is, lastvp, vp);
1498 delay = compute_target_delay(last_duration, is);
1500 time= av_gettime_relative()/1000000.0;
1501 if (time < is->frame_timer + delay && !redisplay) {
1502 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1506 is->frame_timer += delay;
1507 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1508 is->frame_timer = time;
1510 SDL_LockMutex(is->pictq.mutex);
1511 if (!redisplay && !isnan(vp->pts))
1512 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1513 SDL_UnlockMutex(is->pictq.mutex);
1515 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1516 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1517 duration = vp_duration(is, vp, nextvp);
1518 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1520 is->frame_drops_late++;
1521 frame_queue_next(&is->pictq);
1527 if (is->subtitle_st) {
1528 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1529 sp = frame_queue_peek(&is->subpq);
1531 if (frame_queue_nb_remaining(&is->subpq) > 1)
1532 sp2 = frame_queue_peek_next(&is->subpq);
1536 if (sp->serial != is->subtitleq.serial
1537 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1538 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1540 frame_queue_next(&is->subpq);
1548 /* display picture */
1549 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1552 frame_queue_next(&is->pictq);
1554 if (is->step && !is->paused)
1555 stream_toggle_pause(is);
1558 is->force_refresh = 0;
1560 static int64_t last_time;
1562 int aqsize, vqsize, sqsize;
1565 cur_time = av_gettime_relative();
1566 if (!last_time || (cur_time - last_time) >= 30000) {
1571 aqsize = is->audioq.size;
1573 vqsize = is->videoq.size;
1574 if (is->subtitle_st)
1575 sqsize = is->subtitleq.size;
1577 if (is->audio_st && is->video_st)
1578 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1579 else if (is->video_st)
1580 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1581 else if (is->audio_st)
1582 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1583 av_log(NULL, AV_LOG_INFO,
1584 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1585 get_master_clock(is),
1586 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1588 is->frame_drops_early + is->frame_drops_late,
1592 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1593 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1595 last_time = cur_time;
1600 /* allocate a picture (needs to do that in main thread to avoid
1601 potential locking problems */
1602 static void alloc_picture(VideoState *is)
1607 vp = &is->pictq.queue[is->pictq.windex];
1611 video_open(is, 0, vp);
1613 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1616 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1617 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1618 /* SDL allocates a buffer smaller than requested if the video
1619 * overlay hardware is unable to support the requested size. */
1620 av_log(NULL, AV_LOG_FATAL,
1621 "Error: the video system does not support an image\n"
1622 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1623 "to reduce the image size.\n", vp->width, vp->height );
1627 SDL_LockMutex(is->pictq.mutex);
1629 SDL_CondSignal(is->pictq.cond);
1630 SDL_UnlockMutex(is->pictq.mutex);
1633 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1634 int i, width, height;
1636 for (i = 0; i < 3; i++) {
1643 if (bmp->pitches[i] > width) {
1644 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1645 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1651 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1655 #if defined(DEBUG_SYNC) && 0
1656 printf("frame_type=%c pts=%0.3f\n",
1657 av_get_picture_type_char(src_frame->pict_type), pts);
1660 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1663 vp->sar = src_frame->sample_aspect_ratio;
1665 /* alloc or resize hardware picture buffer */
1666 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1667 vp->width != src_frame->width ||
1668 vp->height != src_frame->height) {
1673 vp->width = src_frame->width;
1674 vp->height = src_frame->height;
1676 /* the allocation must be done in the main thread to avoid
1677 locking problems. */
1678 event.type = FF_ALLOC_EVENT;
1679 event.user.data1 = is;
1680 SDL_PushEvent(&event);
1682 /* wait until the picture is allocated */
1683 SDL_LockMutex(is->pictq.mutex);
1684 while (!vp->allocated && !is->videoq.abort_request) {
1685 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1687 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1688 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1689 while (!vp->allocated && !is->abort_request) {
1690 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1693 SDL_UnlockMutex(is->pictq.mutex);
1695 if (is->videoq.abort_request)
1699 /* if the frame is not skipped, then display it */
1701 AVPicture pict = { { 0 } };
1703 /* get a pointer on the bitmap */
1704 SDL_LockYUVOverlay (vp->bmp);
1706 pict.data[0] = vp->bmp->pixels[0];
1707 pict.data[1] = vp->bmp->pixels[2];
1708 pict.data[2] = vp->bmp->pixels[1];
1710 pict.linesize[0] = vp->bmp->pitches[0];
1711 pict.linesize[1] = vp->bmp->pitches[2];
1712 pict.linesize[2] = vp->bmp->pitches[1];
1715 // FIXME use direct rendering
1716 av_picture_copy(&pict, (AVPicture *)src_frame,
1717 src_frame->format, vp->width, vp->height);
1719 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1720 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1721 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1722 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1723 if (!is->img_convert_ctx) {
1724 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1727 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1728 0, vp->height, pict.data, pict.linesize);
1730 /* workaround SDL PITCH_WORKAROUND */
1731 duplicate_right_border_pixels(vp->bmp);
1732 /* update the bitmap content */
1733 SDL_UnlockYUVOverlay(vp->bmp);
1736 vp->duration = duration;
1738 vp->serial = serial;
1740 /* now we can update the picture count */
1741 frame_queue_push(&is->pictq);
1746 static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *serial)
1750 if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
1753 if (pkt->data == flush_pkt.data) {
1754 avcodec_flush_buffers(is->video_st->codec);
1758 if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
1761 if (!got_picture && !pkt->data)
1762 is->video_finished = *serial;
1768 if (decoder_reorder_pts == -1) {
1769 frame->pts = av_frame_get_best_effort_timestamp(frame);
1770 } else if (decoder_reorder_pts) {
1771 frame->pts = frame->pkt_pts;
1773 frame->pts = frame->pkt_dts;
1776 if (frame->pts != AV_NOPTS_VALUE)
1777 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1779 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1781 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1782 if (frame->pts != AV_NOPTS_VALUE) {
1783 double diff = dpts - get_master_clock(is);
1784 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1785 diff - is->frame_last_filter_delay < 0 &&
1786 *serial == is->vidclk.serial &&
1787 is->videoq.nb_packets) {
1788 is->frame_drops_early++;
1789 av_frame_unref(frame);
1801 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1802 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1805 int nb_filters = graph->nb_filters;
1806 AVFilterInOut *outputs = NULL, *inputs = NULL;
1809 outputs = avfilter_inout_alloc();
1810 inputs = avfilter_inout_alloc();
1811 if (!outputs || !inputs) {
1812 ret = AVERROR(ENOMEM);
1816 outputs->name = av_strdup("in");
1817 outputs->filter_ctx = source_ctx;
1818 outputs->pad_idx = 0;
1819 outputs->next = NULL;
1821 inputs->name = av_strdup("out");
1822 inputs->filter_ctx = sink_ctx;
1823 inputs->pad_idx = 0;
1824 inputs->next = NULL;
1826 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1829 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1833 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1834 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1835 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1837 ret = avfilter_graph_config(graph, NULL);
1839 avfilter_inout_free(&outputs);
1840 avfilter_inout_free(&inputs);
1844 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1846 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1847 char sws_flags_str[128];
1848 char buffersrc_args[256];
1850 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1851 AVCodecContext *codec = is->video_st->codec;
1852 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1854 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1855 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1856 graph->scale_sws_opts = av_strdup(sws_flags_str);
1858 snprintf(buffersrc_args, sizeof(buffersrc_args),
1859 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1860 frame->width, frame->height, frame->format,
1861 is->video_st->time_base.num, is->video_st->time_base.den,
1862 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1863 if (fr.num && fr.den)
1864 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1866 if ((ret = avfilter_graph_create_filter(&filt_src,
1867 avfilter_get_by_name("buffer"),
1868 "ffplay_buffer", buffersrc_args, NULL,
1872 ret = avfilter_graph_create_filter(&filt_out,
1873 avfilter_get_by_name("buffersink"),
1874 "ffplay_buffersink", NULL, NULL, graph);
1878 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1881 last_filter = filt_out;
1883 /* Note: this macro adds a filter before the lastly added filter, so the
1884 * processing order of the filters is in reverse */
1885 #define INSERT_FILT(name, arg) do { \
1886 AVFilterContext *filt_ctx; \
1888 ret = avfilter_graph_create_filter(&filt_ctx, \
1889 avfilter_get_by_name(name), \
1890 "ffplay_" name, arg, NULL, graph); \
1894 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1898 last_filter = filt_ctx; \
1901 /* SDL YUV code is not handling odd width/height for some driver
1902 * combinations, therefore we crop the picture to an even width/height. */
1903 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1906 AVDictionaryEntry *rotate_tag = av_dict_get(is->video_st->metadata, "rotate", NULL, 0);
1907 if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
1908 if (!strcmp(rotate_tag->value, "90")) {
1909 INSERT_FILT("transpose", "clock");
1910 } else if (!strcmp(rotate_tag->value, "180")) {
1911 INSERT_FILT("hflip", NULL);
1912 INSERT_FILT("vflip", NULL);
1913 } else if (!strcmp(rotate_tag->value, "270")) {
1914 INSERT_FILT("transpose", "cclock");
1916 char rotate_buf[64];
1917 snprintf(rotate_buf, sizeof(rotate_buf), "%s*PI/180", rotate_tag->value);
1918 INSERT_FILT("rotate", rotate_buf);
1923 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1926 is->in_video_filter = filt_src;
1927 is->out_video_filter = filt_out;
1933 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1935 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1936 int sample_rates[2] = { 0, -1 };
1937 int64_t channel_layouts[2] = { 0, -1 };
1938 int channels[2] = { 0, -1 };
1939 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1940 char aresample_swr_opts[512] = "";
1941 AVDictionaryEntry *e = NULL;
1942 char asrc_args[256];
1945 avfilter_graph_free(&is->agraph);
1946 if (!(is->agraph = avfilter_graph_alloc()))
1947 return AVERROR(ENOMEM);
1949 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1950 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1951 if (strlen(aresample_swr_opts))
1952 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1953 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1955 ret = snprintf(asrc_args, sizeof(asrc_args),
1956 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1957 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1958 is->audio_filter_src.channels,
1959 1, is->audio_filter_src.freq);
1960 if (is->audio_filter_src.channel_layout)
1961 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1962 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1964 ret = avfilter_graph_create_filter(&filt_asrc,
1965 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1966 asrc_args, NULL, is->agraph);
1971 ret = avfilter_graph_create_filter(&filt_asink,
1972 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1973 NULL, NULL, is->agraph);
1977 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1979 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1982 if (force_output_format) {
1983 channel_layouts[0] = is->audio_tgt.channel_layout;
1984 channels [0] = is->audio_tgt.channels;
1985 sample_rates [0] = is->audio_tgt.freq;
1986 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1988 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1990 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1992 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1997 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
2000 is->in_audio_filter = filt_asrc;
2001 is->out_audio_filter = filt_asink;
2005 avfilter_graph_free(&is->agraph);
2008 #endif /* CONFIG_AVFILTER */
2010 static int video_thread(void *arg)
2012 AVPacket pkt = { 0 };
2013 VideoState *is = arg;
2014 AVFrame *frame = av_frame_alloc();
2019 AVRational tb = is->video_st->time_base;
2020 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2023 AVFilterGraph *graph = avfilter_graph_alloc();
2024 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2027 enum AVPixelFormat last_format = -2;
2028 int last_serial = -1;
2029 int last_vfilter_idx = 0;
2033 while (is->paused && !is->videoq.abort_request)
2036 av_free_packet(&pkt);
2038 ret = get_video_frame(is, frame, &pkt, &serial);
2045 if ( last_w != frame->width
2046 || last_h != frame->height
2047 || last_format != frame->format
2048 || last_serial != serial
2049 || last_vfilter_idx != is->vfilter_idx) {
2050 av_log(NULL, AV_LOG_DEBUG,
2051 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2053 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2054 frame->width, frame->height,
2055 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial);
2056 avfilter_graph_free(&graph);
2057 graph = avfilter_graph_alloc();
2058 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2060 event.type = FF_QUIT_EVENT;
2061 event.user.data1 = is;
2062 SDL_PushEvent(&event);
2065 filt_in = is->in_video_filter;
2066 filt_out = is->out_video_filter;
2067 last_w = frame->width;
2068 last_h = frame->height;
2069 last_format = frame->format;
2070 last_serial = serial;
2071 last_vfilter_idx = is->vfilter_idx;
2072 frame_rate = filt_out->inputs[0]->frame_rate;
2075 ret = av_buffersrc_add_frame(filt_in, frame);
2080 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2082 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2084 if (ret == AVERROR_EOF)
2085 is->video_finished = serial;
2090 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2091 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2092 is->frame_last_filter_delay = 0;
2093 tb = filt_out->inputs[0]->time_base;
2095 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2096 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2097 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), serial);
2098 av_frame_unref(frame);
2108 avfilter_graph_free(&graph);
2110 av_free_packet(&pkt);
2111 av_frame_free(&frame);
2115 static int subtitle_thread(void *arg)
2117 VideoState *is = arg;
2119 AVPacket pkt1, *pkt = &pkt1;
2124 int r, g, b, y, u, v, a;
2127 while (is->paused && !is->subtitleq.abort_request) {
2130 if (packet_queue_get(&is->subtitleq, pkt, 1, &serial) < 0)
2133 if (pkt->data == flush_pkt.data) {
2134 avcodec_flush_buffers(is->subtitle_st->codec);
2138 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2141 /* NOTE: ipts is the PTS of the _first_ picture beginning in
2142 this packet, if any */
2144 if (pkt->pts != AV_NOPTS_VALUE)
2145 pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
2147 avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
2148 &got_subtitle, pkt);
2149 if (got_subtitle && sp->sub.format == 0) {
2150 if (sp->sub.pts != AV_NOPTS_VALUE)
2151 pts = sp->sub.pts / (double)AV_TIME_BASE;
2153 sp->serial = serial;
2155 for (i = 0; i < sp->sub.num_rects; i++)
2157 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2159 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2160 y = RGB_TO_Y_CCIR(r, g, b);
2161 u = RGB_TO_U_CCIR(r, g, b, 0);
2162 v = RGB_TO_V_CCIR(r, g, b, 0);
2163 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2167 /* now we can update the picture count */
2168 frame_queue_push(&is->subpq);
2169 } else if (got_subtitle) {
2170 avsubtitle_free(&sp->sub);
2172 av_free_packet(pkt);
2177 /* copy samples for viewing in editor window */
2178 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2182 size = samples_size / sizeof(short);
2184 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2187 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2189 is->sample_array_index += len;
2190 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2191 is->sample_array_index = 0;
2196 /* return the wanted number of samples to get better sync if sync_type is video
2197 * or external master clock */
2198 static int synchronize_audio(VideoState *is, int nb_samples)
2200 int wanted_nb_samples = nb_samples;
2202 /* if not master, then we try to remove or add samples to correct the clock */
2203 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2204 double diff, avg_diff;
2205 int min_nb_samples, max_nb_samples;
2207 diff = get_clock(&is->audclk) - get_master_clock(is);
2209 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2210 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2211 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2212 /* not enough measures to have a correct estimate */
2213 is->audio_diff_avg_count++;
2215 /* estimate the A-V difference */
2216 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2218 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2219 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2220 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2221 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2222 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2224 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2225 diff, avg_diff, wanted_nb_samples - nb_samples,
2226 is->audio_clock, is->audio_diff_threshold);
2229 /* too big difference : may be initial PTS errors, so
2231 is->audio_diff_avg_count = 0;
2232 is->audio_diff_cum = 0;
2236 return wanted_nb_samples;
2240 * Decode one audio frame and return its uncompressed size.
2242 * The processed audio frame is decoded, converted if required, and
2243 * stored in is->audio_buf, with size in bytes given by the return
2246 static int audio_decode_frame(VideoState *is)
2248 AVPacket *pkt_temp = &is->audio_pkt_temp;
2249 AVPacket *pkt = &is->audio_pkt;
2250 AVCodecContext *dec = is->audio_st->codec;
2251 int len1, data_size, resampled_data_size;
2252 int64_t dec_channel_layout;
2254 av_unused double audio_clock0;
2255 int wanted_nb_samples;
2261 /* NOTE: the audio packet can contain several frames */
2262 while (pkt_temp->stream_index != -1 || is->audio_buf_frames_pending) {
2264 if (!(is->frame = av_frame_alloc()))
2265 return AVERROR(ENOMEM);
2267 av_frame_unref(is->frame);
2270 if (is->audioq.serial != is->audio_pkt_temp_serial)
2276 if (!is->audio_buf_frames_pending) {
2277 len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2279 /* if error, we skip the frame */
2285 pkt_temp->pts = AV_NOPTS_VALUE;
2286 pkt_temp->data += len1;
2287 pkt_temp->size -= len1;
2288 if (pkt_temp->data && pkt_temp->size <= 0 || !pkt_temp->data && !got_frame)
2289 pkt_temp->stream_index = -1;
2290 if (!pkt_temp->data && !got_frame)
2291 is->audio_finished = is->audio_pkt_temp_serial;
2296 tb = (AVRational){1, is->frame->sample_rate};
2297 if (is->frame->pts != AV_NOPTS_VALUE)
2298 is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
2299 else if (is->frame->pkt_pts != AV_NOPTS_VALUE)
2300 is->frame->pts = av_rescale_q(is->frame->pkt_pts, is->audio_st->time_base, tb);
2301 else if (is->audio_frame_next_pts != AV_NOPTS_VALUE)
2303 is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_filter_src.freq}, tb);
2305 is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_src.freq}, tb);
2308 if (is->frame->pts != AV_NOPTS_VALUE)
2309 is->audio_frame_next_pts = is->frame->pts + is->frame->nb_samples;
2312 dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
2315 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2316 is->frame->format, av_frame_get_channels(is->frame)) ||
2317 is->audio_filter_src.channel_layout != dec_channel_layout ||
2318 is->audio_filter_src.freq != is->frame->sample_rate ||
2319 is->audio_pkt_temp_serial != is->audio_last_serial;
2322 char buf1[1024], buf2[1024];
2323 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2324 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2325 av_log(NULL, AV_LOG_DEBUG,
2326 "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",
2327 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,
2328 is->frame->sample_rate, av_frame_get_channels(is->frame), av_get_sample_fmt_name(is->frame->format), buf2, is->audio_pkt_temp_serial);
2330 is->audio_filter_src.fmt = is->frame->format;
2331 is->audio_filter_src.channels = av_frame_get_channels(is->frame);
2332 is->audio_filter_src.channel_layout = dec_channel_layout;
2333 is->audio_filter_src.freq = is->frame->sample_rate;
2334 is->audio_last_serial = is->audio_pkt_temp_serial;
2336 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2340 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
2345 if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
2346 if (ret == AVERROR(EAGAIN)) {
2347 is->audio_buf_frames_pending = 0;
2350 if (ret == AVERROR_EOF)
2351 is->audio_finished = is->audio_pkt_temp_serial;
2354 is->audio_buf_frames_pending = 1;
2355 tb = is->out_audio_filter->inputs[0]->time_base;
2358 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
2359 is->frame->nb_samples,
2360 is->frame->format, 1);
2362 dec_channel_layout =
2363 (is->frame->channel_layout && av_frame_get_channels(is->frame) == av_get_channel_layout_nb_channels(is->frame->channel_layout)) ?
2364 is->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(is->frame));
2365 wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2367 if (is->frame->format != is->audio_src.fmt ||
2368 dec_channel_layout != is->audio_src.channel_layout ||
2369 is->frame->sample_rate != is->audio_src.freq ||
2370 (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2371 swr_free(&is->swr_ctx);
2372 is->swr_ctx = swr_alloc_set_opts(NULL,
2373 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2374 dec_channel_layout, is->frame->format, is->frame->sample_rate,
2376 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2377 av_log(NULL, AV_LOG_ERROR,
2378 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2379 is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
2380 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2383 is->audio_src.channel_layout = dec_channel_layout;
2384 is->audio_src.channels = av_frame_get_channels(is->frame);
2385 is->audio_src.freq = is->frame->sample_rate;
2386 is->audio_src.fmt = is->frame->format;
2390 const uint8_t **in = (const uint8_t **)is->frame->extended_data;
2391 uint8_t **out = &is->audio_buf1;
2392 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
2393 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2396 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2399 if (wanted_nb_samples != is->frame->nb_samples) {
2400 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
2401 wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
2402 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2406 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2407 if (!is->audio_buf1)
2408 return AVERROR(ENOMEM);
2409 len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
2411 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2414 if (len2 == out_count) {
2415 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2416 swr_init(is->swr_ctx);
2418 is->audio_buf = is->audio_buf1;
2419 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2421 is->audio_buf = is->frame->data[0];
2422 resampled_data_size = data_size;
2425 audio_clock0 = is->audio_clock;
2426 /* update the audio clock with the pts */
2427 if (is->frame->pts != AV_NOPTS_VALUE)
2428 is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
2430 is->audio_clock = NAN;
2431 is->audio_clock_serial = is->audio_pkt_temp_serial;
2434 static double last_clock;
2435 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2436 is->audio_clock - last_clock,
2437 is->audio_clock, audio_clock0);
2438 last_clock = is->audio_clock;
2441 return resampled_data_size;
2444 /* free the current packet */
2446 av_free_packet(pkt);
2447 memset(pkt_temp, 0, sizeof(*pkt_temp));
2448 pkt_temp->stream_index = -1;
2450 if (is->audioq.abort_request) {
2454 if (is->audioq.nb_packets == 0)
2455 SDL_CondSignal(is->continue_read_thread);
2457 /* read next packet */
2458 if ((packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
2461 if (pkt->data == flush_pkt.data) {
2462 avcodec_flush_buffers(dec);
2463 is->audio_buf_frames_pending = 0;
2464 is->audio_frame_next_pts = AV_NOPTS_VALUE;
2465 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek)
2466 is->audio_frame_next_pts = is->audio_st->start_time;
2473 /* prepare a new audio buffer */
2474 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2476 VideoState *is = opaque;
2477 int audio_size, len1;
2479 audio_callback_time = av_gettime_relative();
2482 if (is->audio_buf_index >= is->audio_buf_size) {
2483 audio_size = audio_decode_frame(is);
2484 if (audio_size < 0) {
2485 /* if error, just output silence */
2486 is->audio_buf = is->silence_buf;
2487 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2489 if (is->show_mode != SHOW_MODE_VIDEO)
2490 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2491 is->audio_buf_size = audio_size;
2493 is->audio_buf_index = 0;
2495 len1 = is->audio_buf_size - is->audio_buf_index;
2498 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2501 is->audio_buf_index += len1;
2503 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2504 /* Let's assume the audio driver that is used by SDL has two periods. */
2505 if (!isnan(is->audio_clock)) {
2506 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);
2507 sync_clock_to_slave(&is->extclk, &is->audclk);
2511 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2513 SDL_AudioSpec wanted_spec, spec;
2515 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2516 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2517 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2519 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2521 wanted_nb_channels = atoi(env);
2522 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2524 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2525 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2526 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2528 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2529 wanted_spec.channels = wanted_nb_channels;
2530 wanted_spec.freq = wanted_sample_rate;
2531 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2532 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2535 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2536 next_sample_rate_idx--;
2537 wanted_spec.format = AUDIO_S16SYS;
2538 wanted_spec.silence = 0;
2539 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2540 wanted_spec.callback = sdl_audio_callback;
2541 wanted_spec.userdata = opaque;
2542 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2543 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2544 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2545 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2546 if (!wanted_spec.channels) {
2547 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2548 wanted_spec.channels = wanted_nb_channels;
2549 if (!wanted_spec.freq) {
2550 av_log(NULL, AV_LOG_ERROR,
2551 "No more combinations to try, audio open failed\n");
2555 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2557 if (spec.format != AUDIO_S16SYS) {
2558 av_log(NULL, AV_LOG_ERROR,
2559 "SDL advised audio format %d is not supported!\n", spec.format);
2562 if (spec.channels != wanted_spec.channels) {
2563 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2564 if (!wanted_channel_layout) {
2565 av_log(NULL, AV_LOG_ERROR,
2566 "SDL advised channel count %d is not supported!\n", spec.channels);
2571 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2572 audio_hw_params->freq = spec.freq;
2573 audio_hw_params->channel_layout = wanted_channel_layout;
2574 audio_hw_params->channels = spec.channels;
2575 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2576 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);
2577 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2578 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2584 /* open a given stream. Return 0 if OK */
2585 static int stream_component_open(VideoState *is, int stream_index)
2587 AVFormatContext *ic = is->ic;
2588 AVCodecContext *avctx;
2590 const char *forced_codec_name = NULL;
2592 AVDictionaryEntry *t = NULL;
2593 int sample_rate, nb_channels;
2594 int64_t channel_layout;
2596 int stream_lowres = lowres;
2598 if (stream_index < 0 || stream_index >= ic->nb_streams)
2600 avctx = ic->streams[stream_index]->codec;
2602 codec = avcodec_find_decoder(avctx->codec_id);
2604 switch(avctx->codec_type){
2605 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2606 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2607 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2609 if (forced_codec_name)
2610 codec = avcodec_find_decoder_by_name(forced_codec_name);
2612 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2613 "No codec could be found with name '%s'\n", forced_codec_name);
2614 else av_log(NULL, AV_LOG_WARNING,
2615 "No codec could be found with id %d\n", avctx->codec_id);
2619 avctx->codec_id = codec->id;
2620 avctx->workaround_bugs = workaround_bugs;
2621 if(stream_lowres > av_codec_get_max_lowres(codec)){
2622 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2623 av_codec_get_max_lowres(codec));
2624 stream_lowres = av_codec_get_max_lowres(codec);
2626 av_codec_set_lowres(avctx, stream_lowres);
2628 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2629 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2630 if(codec->capabilities & CODEC_CAP_DR1)
2631 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2633 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2634 if (!av_dict_get(opts, "threads", NULL, 0))
2635 av_dict_set(&opts, "threads", "auto", 0);
2637 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2638 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2639 av_dict_set(&opts, "refcounted_frames", "1", 0);
2640 if (avcodec_open2(avctx, codec, &opts) < 0)
2642 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2643 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2644 return AVERROR_OPTION_NOT_FOUND;
2647 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2648 switch (avctx->codec_type) {
2649 case AVMEDIA_TYPE_AUDIO:
2654 is->audio_filter_src.freq = avctx->sample_rate;
2655 is->audio_filter_src.channels = avctx->channels;
2656 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2657 is->audio_filter_src.fmt = avctx->sample_fmt;
2658 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2660 link = is->out_audio_filter->inputs[0];
2661 sample_rate = link->sample_rate;
2662 nb_channels = link->channels;
2663 channel_layout = link->channel_layout;
2666 sample_rate = avctx->sample_rate;
2667 nb_channels = avctx->channels;
2668 channel_layout = avctx->channel_layout;
2671 /* prepare audio output */
2672 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2674 is->audio_hw_buf_size = ret;
2675 is->audio_src = is->audio_tgt;
2676 is->audio_buf_size = 0;
2677 is->audio_buf_index = 0;
2679 /* init averaging filter */
2680 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2681 is->audio_diff_avg_count = 0;
2682 /* since we do not have a precise anough audio fifo fullness,
2683 we correct audio sync only if larger than this threshold */
2684 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2686 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2687 memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
2688 is->audio_pkt_temp.stream_index = -1;
2690 is->audio_stream = stream_index;
2691 is->audio_st = ic->streams[stream_index];
2693 packet_queue_start(&is->audioq);
2696 case AVMEDIA_TYPE_VIDEO:
2697 is->video_stream = stream_index;
2698 is->video_st = ic->streams[stream_index];
2700 packet_queue_start(&is->videoq);
2701 is->video_tid = SDL_CreateThread(video_thread, is);
2702 is->queue_attachments_req = 1;
2704 case AVMEDIA_TYPE_SUBTITLE:
2705 is->subtitle_stream = stream_index;
2706 is->subtitle_st = ic->streams[stream_index];
2707 packet_queue_start(&is->subtitleq);
2709 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2717 static void stream_component_close(VideoState *is, int stream_index)
2719 AVFormatContext *ic = is->ic;
2720 AVCodecContext *avctx;
2722 if (stream_index < 0 || stream_index >= ic->nb_streams)
2724 avctx = ic->streams[stream_index]->codec;
2726 switch (avctx->codec_type) {
2727 case AVMEDIA_TYPE_AUDIO:
2728 packet_queue_abort(&is->audioq);
2732 packet_queue_flush(&is->audioq);
2733 av_free_packet(&is->audio_pkt);
2734 swr_free(&is->swr_ctx);
2735 av_freep(&is->audio_buf1);
2736 is->audio_buf1_size = 0;
2737 is->audio_buf = NULL;
2738 av_frame_free(&is->frame);
2741 av_rdft_end(is->rdft);
2742 av_freep(&is->rdft_data);
2747 avfilter_graph_free(&is->agraph);
2750 case AVMEDIA_TYPE_VIDEO:
2751 packet_queue_abort(&is->videoq);
2753 /* note: we also signal this mutex to make sure we deblock the
2754 video thread in all cases */
2755 frame_queue_signal(&is->pictq);
2757 SDL_WaitThread(is->video_tid, NULL);
2759 packet_queue_flush(&is->videoq);
2761 case AVMEDIA_TYPE_SUBTITLE:
2762 packet_queue_abort(&is->subtitleq);
2764 /* note: we also signal this mutex to make sure we deblock the
2765 video thread in all cases */
2766 frame_queue_signal(&is->subpq);
2768 SDL_WaitThread(is->subtitle_tid, NULL);
2770 packet_queue_flush(&is->subtitleq);
2776 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2777 avcodec_close(avctx);
2778 switch (avctx->codec_type) {
2779 case AVMEDIA_TYPE_AUDIO:
2780 is->audio_st = NULL;
2781 is->audio_stream = -1;
2783 case AVMEDIA_TYPE_VIDEO:
2784 is->video_st = NULL;
2785 is->video_stream = -1;
2787 case AVMEDIA_TYPE_SUBTITLE:
2788 is->subtitle_st = NULL;
2789 is->subtitle_stream = -1;
2796 static int decode_interrupt_cb(void *ctx)
2798 VideoState *is = ctx;
2799 return is->abort_request;
2802 static int is_realtime(AVFormatContext *s)
2804 if( !strcmp(s->iformat->name, "rtp")
2805 || !strcmp(s->iformat->name, "rtsp")
2806 || !strcmp(s->iformat->name, "sdp")
2810 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2811 || !strncmp(s->filename, "udp:", 4)
2818 /* this thread gets the stream from the disk or the network */
2819 static int read_thread(void *arg)
2821 VideoState *is = arg;
2822 AVFormatContext *ic = NULL;
2824 int st_index[AVMEDIA_TYPE_NB];
2825 AVPacket pkt1, *pkt = &pkt1;
2827 int64_t stream_start_time;
2828 int pkt_in_play_range = 0;
2829 AVDictionaryEntry *t;
2830 AVDictionary **opts;
2831 int orig_nb_streams;
2832 SDL_mutex *wait_mutex = SDL_CreateMutex();
2834 memset(st_index, -1, sizeof(st_index));
2835 is->last_video_stream = is->video_stream = -1;
2836 is->last_audio_stream = is->audio_stream = -1;
2837 is->last_subtitle_stream = is->subtitle_stream = -1;
2839 ic = avformat_alloc_context();
2840 ic->interrupt_callback.callback = decode_interrupt_cb;
2841 ic->interrupt_callback.opaque = is;
2842 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2844 print_error(is->filename, err);
2848 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2849 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2850 ret = AVERROR_OPTION_NOT_FOUND;
2856 ic->flags |= AVFMT_FLAG_GENPTS;
2858 av_format_inject_global_side_data(ic);
2860 opts = setup_find_stream_info_opts(ic, codec_opts);
2861 orig_nb_streams = ic->nb_streams;
2863 err = avformat_find_stream_info(ic, opts);
2865 av_log(NULL, AV_LOG_WARNING,
2866 "%s: could not find codec parameters\n", is->filename);
2870 for (i = 0; i < orig_nb_streams; i++)
2871 av_dict_free(&opts[i]);
2875 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2877 if (seek_by_bytes < 0)
2878 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2880 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2882 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2883 window_title = av_asprintf("%s - %s", t->value, input_filename);
2885 /* if seeking requested, we execute it */
2886 if (start_time != AV_NOPTS_VALUE) {
2889 timestamp = start_time;
2890 /* add the stream start time */
2891 if (ic->start_time != AV_NOPTS_VALUE)
2892 timestamp += ic->start_time;
2893 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2895 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2896 is->filename, (double)timestamp / AV_TIME_BASE);
2900 is->realtime = is_realtime(ic);
2902 for (i = 0; i < ic->nb_streams; i++)
2903 ic->streams[i]->discard = AVDISCARD_ALL;
2905 st_index[AVMEDIA_TYPE_VIDEO] =
2906 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2907 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2909 st_index[AVMEDIA_TYPE_AUDIO] =
2910 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2911 wanted_stream[AVMEDIA_TYPE_AUDIO],
2912 st_index[AVMEDIA_TYPE_VIDEO],
2914 if (!video_disable && !subtitle_disable)
2915 st_index[AVMEDIA_TYPE_SUBTITLE] =
2916 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2917 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2918 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2919 st_index[AVMEDIA_TYPE_AUDIO] :
2920 st_index[AVMEDIA_TYPE_VIDEO]),
2923 av_dump_format(ic, 0, is->filename, 0);
2926 is->show_mode = show_mode;
2927 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2928 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2929 AVCodecContext *avctx = st->codec;
2930 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2932 set_default_window_size(avctx->width, avctx->height, sar);
2935 /* open the streams */
2936 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2937 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2941 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2942 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2944 if (is->show_mode == SHOW_MODE_NONE)
2945 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2947 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2948 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2951 if (is->video_stream < 0 && is->audio_stream < 0) {
2952 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2958 if (infinite_buffer < 0 && is->realtime)
2959 infinite_buffer = 1;
2962 if (is->abort_request)
2964 if (is->paused != is->last_paused) {
2965 is->last_paused = is->paused;
2967 is->read_pause_return = av_read_pause(ic);
2971 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2973 (!strcmp(ic->iformat->name, "rtsp") ||
2974 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2975 /* wait 10 ms to avoid trying to get another packet */
2982 int64_t seek_target = is->seek_pos;
2983 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2984 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2985 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2986 // of the seek_pos/seek_rel variables
2988 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2990 av_log(NULL, AV_LOG_ERROR,
2991 "%s: error while seeking\n", is->ic->filename);
2993 if (is->audio_stream >= 0) {
2994 packet_queue_flush(&is->audioq);
2995 packet_queue_put(&is->audioq, &flush_pkt);
2997 if (is->subtitle_stream >= 0) {
2998 packet_queue_flush(&is->subtitleq);
2999 packet_queue_put(&is->subtitleq, &flush_pkt);
3001 if (is->video_stream >= 0) {
3002 packet_queue_flush(&is->videoq);
3003 packet_queue_put(&is->videoq, &flush_pkt);
3005 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3006 set_clock(&is->extclk, NAN, 0);
3008 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3012 is->queue_attachments_req = 1;
3015 step_to_next_frame(is);
3017 if (is->queue_attachments_req) {
3018 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3020 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3022 packet_queue_put(&is->videoq, ©);
3023 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3025 is->queue_attachments_req = 0;
3028 /* if the queue are full, no need to read more */
3029 if (infinite_buffer<1 &&
3030 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3031 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3032 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3033 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3034 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3036 SDL_LockMutex(wait_mutex);
3037 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3038 SDL_UnlockMutex(wait_mutex);
3042 (!is->audio_st || is->audio_finished == is->audioq.serial) &&
3043 (!is->video_st || (is->video_finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3044 if (loop != 1 && (!loop || --loop)) {
3045 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3046 } else if (autoexit) {
3052 if (is->video_stream >= 0)
3053 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3054 if (is->audio_stream >= 0)
3055 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3056 if (is->subtitle_stream >= 0)
3057 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3062 ret = av_read_frame(ic, pkt);
3064 if (ret == AVERROR_EOF || avio_feof(ic->pb))
3066 if (ic->pb && ic->pb->error)
3068 SDL_LockMutex(wait_mutex);
3069 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3070 SDL_UnlockMutex(wait_mutex);
3073 /* check if packet is in play range specified by user, then queue, otherwise discard */
3074 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3075 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3076 (pkt->pts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3077 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3078 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3079 <= ((double)duration / 1000000);
3080 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3081 packet_queue_put(&is->audioq, pkt);
3082 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3083 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3084 packet_queue_put(&is->videoq, pkt);
3085 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3086 packet_queue_put(&is->subtitleq, pkt);
3088 av_free_packet(pkt);
3091 /* wait until the end */
3092 while (!is->abort_request) {
3098 /* close each stream */
3099 if (is->audio_stream >= 0)
3100 stream_component_close(is, is->audio_stream);
3101 if (is->video_stream >= 0)
3102 stream_component_close(is, is->video_stream);
3103 if (is->subtitle_stream >= 0)
3104 stream_component_close(is, is->subtitle_stream);
3106 avformat_close_input(&is->ic);
3112 event.type = FF_QUIT_EVENT;
3113 event.user.data1 = is;
3114 SDL_PushEvent(&event);
3116 SDL_DestroyMutex(wait_mutex);
3120 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3124 is = av_mallocz(sizeof(VideoState));
3127 av_strlcpy(is->filename, filename, sizeof(is->filename));
3128 is->iformat = iformat;
3132 /* start video display */
3133 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3135 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3138 packet_queue_init(&is->videoq);
3139 packet_queue_init(&is->audioq);
3140 packet_queue_init(&is->subtitleq);
3142 is->continue_read_thread = SDL_CreateCond();
3144 init_clock(&is->vidclk, &is->videoq.serial);
3145 init_clock(&is->audclk, &is->audioq.serial);
3146 init_clock(&is->extclk, &is->extclk.serial);
3147 is->audio_clock_serial = -1;
3148 is->audio_last_serial = -1;
3149 is->av_sync_type = av_sync_type;
3150 is->read_tid = SDL_CreateThread(read_thread, is);
3151 if (!is->read_tid) {
3159 static void stream_cycle_channel(VideoState *is, int codec_type)
3161 AVFormatContext *ic = is->ic;
3162 int start_index, stream_index;
3165 AVProgram *p = NULL;
3166 int nb_streams = is->ic->nb_streams;
3168 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3169 start_index = is->last_video_stream;
3170 old_index = is->video_stream;
3171 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3172 start_index = is->last_audio_stream;
3173 old_index = is->audio_stream;
3175 start_index = is->last_subtitle_stream;
3176 old_index = is->subtitle_stream;
3178 stream_index = start_index;
3180 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3181 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3183 nb_streams = p->nb_stream_indexes;
3184 for (start_index = 0; start_index < nb_streams; start_index++)
3185 if (p->stream_index[start_index] == stream_index)
3187 if (start_index == nb_streams)
3189 stream_index = start_index;
3194 if (++stream_index >= nb_streams)
3196 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3199 is->last_subtitle_stream = -1;
3202 if (start_index == -1)
3206 if (stream_index == start_index)
3208 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3209 if (st->codec->codec_type == codec_type) {
3210 /* check that parameters are OK */
3211 switch (codec_type) {
3212 case AVMEDIA_TYPE_AUDIO:
3213 if (st->codec->sample_rate != 0 &&
3214 st->codec->channels != 0)
3217 case AVMEDIA_TYPE_VIDEO:
3218 case AVMEDIA_TYPE_SUBTITLE:
3226 if (p && stream_index != -1)
3227 stream_index = p->stream_index[stream_index];
3228 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3229 av_get_media_type_string(codec_type),
3233 stream_component_close(is, old_index);
3234 stream_component_open(is, stream_index);
3238 static void toggle_full_screen(VideoState *is)
3240 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3241 /* OS X needs to reallocate the SDL overlays */
3243 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3244 is->pictq.queue[i].reallocate = 1;
3246 is_full_screen = !is_full_screen;
3247 video_open(is, 1, NULL);
3250 static void toggle_audio_display(VideoState *is)
3252 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3253 int next = is->show_mode;
3255 next = (next + 1) % SHOW_MODE_NB;
3256 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3257 if (is->show_mode != next) {
3258 fill_rectangle(screen,
3259 is->xleft, is->ytop, is->width, is->height,
3261 is->force_refresh = 1;
3262 is->show_mode = next;
3266 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3267 double remaining_time = 0.0;
3269 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3270 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3274 if (remaining_time > 0.0)
3275 av_usleep((int64_t)(remaining_time * 1000000.0));
3276 remaining_time = REFRESH_RATE;
3277 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3278 video_refresh(is, &remaining_time);
3283 static void seek_chapter(VideoState *is, int incr)
3285 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3288 if (!is->ic->nb_chapters)
3291 /* find the current chapter */
3292 for (i = 0; i < is->ic->nb_chapters; i++) {
3293 AVChapter *ch = is->ic->chapters[i];
3294 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3302 if (i >= is->ic->nb_chapters)
3305 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3306 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3307 AV_TIME_BASE_Q), 0, 0);
3310 /* handle an event sent by the GUI */
3311 static void event_loop(VideoState *cur_stream)
3314 double incr, pos, frac;
3318 refresh_loop_wait_event(cur_stream, &event);
3319 switch (event.type) {
3321 if (exit_on_keydown) {
3322 do_exit(cur_stream);
3325 switch (event.key.keysym.sym) {
3328 do_exit(cur_stream);
3331 toggle_full_screen(cur_stream);
3332 cur_stream->force_refresh = 1;
3336 toggle_pause(cur_stream);
3338 case SDLK_s: // S: Step to next frame
3339 step_to_next_frame(cur_stream);
3342 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3345 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3348 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3349 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3350 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3353 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3357 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3358 if (++cur_stream->vfilter_idx >= nb_vfilters)
3359 cur_stream->vfilter_idx = 0;
3361 cur_stream->vfilter_idx = 0;
3362 toggle_audio_display(cur_stream);
3365 toggle_audio_display(cur_stream);
3369 if (cur_stream->ic->nb_chapters <= 1) {
3373 seek_chapter(cur_stream, 1);
3376 if (cur_stream->ic->nb_chapters <= 1) {
3380 seek_chapter(cur_stream, -1);
3394 if (seek_by_bytes) {
3396 if (pos < 0 && cur_stream->video_stream >= 0)
3397 pos = frame_queue_last_pos(&cur_stream->pictq);
3398 if (pos < 0 && cur_stream->audio_stream >= 0)
3399 pos = cur_stream->audio_pkt.pos;
3401 pos = avio_tell(cur_stream->ic->pb);
3402 if (cur_stream->ic->bit_rate)
3403 incr *= cur_stream->ic->bit_rate / 8.0;
3407 stream_seek(cur_stream, pos, incr, 1);
3409 pos = get_master_clock(cur_stream);
3411 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3413 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3414 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3415 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3422 case SDL_VIDEOEXPOSE:
3423 cur_stream->force_refresh = 1;
3425 case SDL_MOUSEBUTTONDOWN:
3426 if (exit_on_mousedown) {
3427 do_exit(cur_stream);
3430 case SDL_MOUSEMOTION:
3431 if (cursor_hidden) {
3435 cursor_last_shown = av_gettime_relative();
3436 if (event.type == SDL_MOUSEBUTTONDOWN) {
3439 if (event.motion.state != SDL_PRESSED)
3443 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3444 uint64_t size = avio_size(cur_stream->ic->pb);
3445 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3449 int tns, thh, tmm, tss;
3450 tns = cur_stream->ic->duration / 1000000LL;
3452 tmm = (tns % 3600) / 60;
3454 frac = x / cur_stream->width;
3457 mm = (ns % 3600) / 60;
3459 av_log(NULL, AV_LOG_INFO,
3460 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3461 hh, mm, ss, thh, tmm, tss);
3462 ts = frac * cur_stream->ic->duration;
3463 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3464 ts += cur_stream->ic->start_time;
3465 stream_seek(cur_stream, ts, 0, 0);
3468 case SDL_VIDEORESIZE:
3469 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3470 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
3472 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3473 do_exit(cur_stream);
3475 screen_width = cur_stream->width = screen->w;
3476 screen_height = cur_stream->height = screen->h;
3477 cur_stream->force_refresh = 1;
3481 do_exit(cur_stream);
3483 case FF_ALLOC_EVENT:
3484 alloc_picture(event.user.data1);
3492 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3494 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3495 return opt_default(NULL, "video_size", arg);
3498 static int opt_width(void *optctx, const char *opt, const char *arg)
3500 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3504 static int opt_height(void *optctx, const char *opt, const char *arg)
3506 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3510 static int opt_format(void *optctx, const char *opt, const char *arg)
3512 file_iformat = av_find_input_format(arg);
3513 if (!file_iformat) {
3514 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3515 return AVERROR(EINVAL);
3520 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3522 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3523 return opt_default(NULL, "pixel_format", arg);
3526 static int opt_sync(void *optctx, const char *opt, const char *arg)
3528 if (!strcmp(arg, "audio"))
3529 av_sync_type = AV_SYNC_AUDIO_MASTER;
3530 else if (!strcmp(arg, "video"))
3531 av_sync_type = AV_SYNC_VIDEO_MASTER;
3532 else if (!strcmp(arg, "ext"))
3533 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3535 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3541 static int opt_seek(void *optctx, const char *opt, const char *arg)
3543 start_time = parse_time_or_die(opt, arg, 1);
3547 static int opt_duration(void *optctx, const char *opt, const char *arg)
3549 duration = parse_time_or_die(opt, arg, 1);
3553 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3555 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3556 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3557 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3558 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3562 static void opt_input_file(void *optctx, const char *filename)
3564 if (input_filename) {
3565 av_log(NULL, AV_LOG_FATAL,
3566 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3567 filename, input_filename);
3570 if (!strcmp(filename, "-"))
3572 input_filename = filename;
3575 static int opt_codec(void *optctx, const char *opt, const char *arg)
3577 const char *spec = strchr(opt, ':');
3579 av_log(NULL, AV_LOG_ERROR,
3580 "No media specifier was specified in '%s' in option '%s'\n",
3582 return AVERROR(EINVAL);
3586 case 'a' : audio_codec_name = arg; break;
3587 case 's' : subtitle_codec_name = arg; break;
3588 case 'v' : video_codec_name = arg; break;
3590 av_log(NULL, AV_LOG_ERROR,
3591 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3592 return AVERROR(EINVAL);
3599 static const OptionDef options[] = {
3600 #include "cmdutils_common_opts.h"
3601 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3602 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3603 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3604 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3605 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3606 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3607 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3608 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3609 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3610 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3611 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3612 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3613 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3614 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3615 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3616 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3617 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3618 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
3619 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3620 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3621 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3622 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3623 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3624 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3625 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3626 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3627 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3628 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3629 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3630 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3632 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3633 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3635 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3636 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3637 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3638 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3639 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3640 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3641 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3642 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3643 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3647 static void show_usage(void)
3649 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3650 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3651 av_log(NULL, AV_LOG_INFO, "\n");
3654 void show_help_default(const char *opt, const char *arg)
3656 av_log_set_callback(log_callback_help);
3658 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3659 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3661 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3662 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3663 #if !CONFIG_AVFILTER
3664 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3666 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3668 printf("\nWhile playing:\n"
3670 "f toggle full screen\n"
3672 "a cycle audio channel in the current program\n"
3673 "v cycle video channel\n"
3674 "t cycle subtitle channel in the current program\n"
3676 "w cycle video filters or show modes\n"
3677 "s activate frame-step mode\n"
3678 "left/right seek backward/forward 10 seconds\n"
3679 "down/up seek backward/forward 1 minute\n"
3680 "page down/page up seek backward/forward 10 minutes\n"
3681 "mouse click seek to percentage in file corresponding to fraction of width\n"
3685 static int lockmgr(void **mtx, enum AVLockOp op)
3688 case AV_LOCK_CREATE:
3689 *mtx = SDL_CreateMutex();
3693 case AV_LOCK_OBTAIN:
3694 return !!SDL_LockMutex(*mtx);
3695 case AV_LOCK_RELEASE:
3696 return !!SDL_UnlockMutex(*mtx);
3697 case AV_LOCK_DESTROY:
3698 SDL_DestroyMutex(*mtx);
3704 /* Called from the main */
3705 int main(int argc, char **argv)
3709 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3711 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3712 parse_loglevel(argc, argv, options);
3714 /* register all codecs, demux and protocols */
3716 avdevice_register_all();
3719 avfilter_register_all();
3722 avformat_network_init();
3726 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3727 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3729 show_banner(argc, argv, options);
3731 parse_options(NULL, argc, argv, options, opt_input_file);
3733 if (!input_filename) {
3735 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3736 av_log(NULL, AV_LOG_FATAL,
3737 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3741 if (display_disable) {
3744 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3746 flags &= ~SDL_INIT_AUDIO;
3747 if (display_disable)
3748 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3749 #if !defined(_WIN32) && !defined(__APPLE__)
3750 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3752 if (SDL_Init (flags)) {
3753 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3754 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3758 if (!display_disable) {
3759 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3760 fs_screen_width = vi->current_w;
3761 fs_screen_height = vi->current_h;
3764 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3765 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3766 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3768 if (av_lockmgr_register(lockmgr)) {
3769 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3773 av_init_packet(&flush_pkt);
3774 flush_pkt.data = (uint8_t *)&flush_pkt;
3776 is = stream_open(input_filename, file_iformat);
3778 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");