2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/colorspace.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avcodec.h"
52 # include "libavfilter/avfilter.h"
53 # include "libavfilter/buffersink.h"
54 # include "libavfilter/buffersrc.h"
58 #include <SDL_thread.h>
64 const char program_name
[] = "ffplay";
65 const int program_birth_year
= 2003;
67 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
70 /* Minimum SDL audio buffer size, in samples. */
71 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
72 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
73 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
75 /* no AV sync correction is done if below the minimum AV sync threshold */
76 #define AV_SYNC_THRESHOLD_MIN 0.04
77 /* AV sync correction is done if above the maximum AV sync threshold */
78 #define AV_SYNC_THRESHOLD_MAX 0.1
79 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
80 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
81 /* no AV correction is done if too big error */
82 #define AV_NOSYNC_THRESHOLD 10.0
84 /* maximum audio speed change to get correct sync */
85 #define SAMPLE_CORRECTION_PERCENT_MAX 10
87 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
88 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
89 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
90 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
92 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
93 #define AUDIO_DIFF_AVG_NB 20
95 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
96 #define REFRESH_RATE 0.01
98 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
99 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
100 #define SAMPLE_ARRAY_SIZE (8 * 65536)
102 #define CURSOR_HIDE_DELAY 1000000
104 static int64_t sws_flags
= SWS_BICUBIC
;
106 typedef struct MyAVPacketList
{
108 struct MyAVPacketList
*next
;
112 typedef struct PacketQueue
{
113 MyAVPacketList
*first_pkt
, *last_pkt
;
122 #define VIDEO_PICTURE_QUEUE_SIZE 3
123 #define SUBPICTURE_QUEUE_SIZE 16
124 #define SAMPLE_QUEUE_SIZE 9
125 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
127 typedef struct AudioParams
{
130 int64_t channel_layout
;
131 enum AVSampleFormat fmt
;
136 typedef struct Clock
{
137 double pts
; /* clock base */
138 double pts_drift
; /* clock base minus time at which we updated the clock */
141 int serial
; /* clock is based on a packet with this serial */
143 int *queue_serial
; /* pointer to the current packet queue serial, used for obsolete clock detection */
146 /* Common struct for handling all types of decoded data and allocated render buffers. */
147 typedef struct Frame
{
151 double pts
; /* presentation timestamp for the frame */
152 double duration
; /* estimated duration of the frame */
153 int64_t pos
; /* byte position of the frame in the input file */
162 typedef struct FrameQueue
{
163 Frame queue
[FRAME_QUEUE_SIZE
];
176 AV_SYNC_AUDIO_MASTER
, /* default choice */
177 AV_SYNC_VIDEO_MASTER
,
178 AV_SYNC_EXTERNAL_CLOCK
, /* synchronize to an external clock */
181 typedef struct Decoder
{
185 AVCodecContext
*avctx
;
190 SDL_cond
*empty_queue_cond
;
192 AVRational start_pts_tb
;
194 AVRational next_pts_tb
;
197 typedef struct VideoState
{
198 SDL_Thread
*read_tid
;
199 SDL_Thread
*video_tid
;
200 SDL_Thread
*audio_tid
;
201 AVInputFormat
*iformat
;
207 int queue_attachments_req
;
212 int read_pause_return
;
233 int audio_clock_serial
;
234 double audio_diff_cum
; /* used for AV difference average computation */
235 double audio_diff_avg_coef
;
236 double audio_diff_threshold
;
237 int audio_diff_avg_count
;
240 int audio_hw_buf_size
;
241 uint8_t silence_buf
[SDL_AUDIO_MIN_BUFFER_SIZE
];
244 unsigned int audio_buf_size
; /* in bytes */
245 unsigned int audio_buf1_size
;
246 int audio_buf_index
; /* in bytes */
247 int audio_write_buf_size
;
248 struct AudioParams audio_src
;
250 struct AudioParams audio_filter_src
;
252 struct AudioParams audio_tgt
;
253 struct SwrContext
*swr_ctx
;
254 int frame_drops_early
;
255 int frame_drops_late
;
258 SHOW_MODE_NONE
= -1, SHOW_MODE_VIDEO
= 0, SHOW_MODE_WAVES
, SHOW_MODE_RDFT
, SHOW_MODE_NB
260 int16_t sample_array
[SAMPLE_ARRAY_SIZE
];
261 int sample_array_index
;
265 FFTSample
*rdft_data
;
267 double last_vis_time
;
269 SDL_Thread
*subtitle_tid
;
271 AVStream
*subtitle_st
;
272 PacketQueue subtitleq
;
275 double frame_last_returned_time
;
276 double frame_last_filter_delay
;
280 double max_frame_duration
; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
282 struct SwsContext
*img_convert_ctx
;
284 SDL_Rect last_display_rect
;
287 int width
, height
, xleft
, ytop
;
292 AVFilterContext
*in_video_filter
; // the first filter in the video chain
293 AVFilterContext
*out_video_filter
; // the last filter in the video chain
294 AVFilterContext
*in_audio_filter
; // the first filter in the audio chain
295 AVFilterContext
*out_audio_filter
; // the last filter in the audio chain
296 AVFilterGraph
*agraph
; // audio filter graph
299 int last_video_stream
, last_audio_stream
, last_subtitle_stream
;
301 SDL_cond
*continue_read_thread
;
304 /* options specified by the user */
305 static AVInputFormat
*file_iformat
;
306 static const char *input_filename
;
307 static const char *window_title
;
308 static int fs_screen_width
;
309 static int fs_screen_height
;
310 static int default_width
= 640;
311 static int default_height
= 480;
312 static int screen_width
= 0;
313 static int screen_height
= 0;
314 static int audio_disable
;
315 static int video_disable
;
316 static int subtitle_disable
;
317 static int wanted_stream
[AVMEDIA_TYPE_NB
] = {
318 [AVMEDIA_TYPE_AUDIO
] = -1,
319 [AVMEDIA_TYPE_VIDEO
] = -1,
320 [AVMEDIA_TYPE_SUBTITLE
] = -1,
322 static int seek_by_bytes
= -1;
323 static int display_disable
;
324 static int show_status
= 1;
325 static int av_sync_type
= AV_SYNC_AUDIO_MASTER
;
326 static int64_t start_time
= AV_NOPTS_VALUE
;
327 static int64_t duration
= AV_NOPTS_VALUE
;
329 static int genpts
= 0;
330 static int lowres
= 0;
331 static int decoder_reorder_pts
= -1;
333 static int exit_on_keydown
;
334 static int exit_on_mousedown
;
336 static int framedrop
= -1;
337 static int infinite_buffer
= -1;
338 static enum ShowMode show_mode
= SHOW_MODE_NONE
;
339 static const char *audio_codec_name
;
340 static const char *subtitle_codec_name
;
341 static const char *video_codec_name
;
342 double rdftspeed
= 0.02;
343 static int64_t cursor_last_shown
;
344 static int cursor_hidden
= 0;
346 static const char **vfilters_list
= NULL
;
347 static int nb_vfilters
= 0;
348 static char *afilters
= NULL
;
350 static int autorotate
= 1;
352 /* current context */
353 static int is_full_screen
;
354 static int64_t audio_callback_time
;
356 static AVPacket flush_pkt
;
358 #define FF_ALLOC_EVENT (SDL_USEREVENT)
359 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
361 static SDL_Surface
*screen
;
364 static int opt_add_vfilter(void *optctx
, const char *opt
, const char *arg
)
366 GROW_ARRAY(vfilters_list
, nb_vfilters
);
367 vfilters_list
[nb_vfilters
- 1] = arg
;
373 int cmp_audio_fmts(enum AVSampleFormat fmt1
, int64_t channel_count1
,
374 enum AVSampleFormat fmt2
, int64_t channel_count2
)
376 /* If channel count == 1, planar and non-planar formats are the same */
377 if (channel_count1
== 1 && channel_count2
== 1)
378 return av_get_packed_sample_fmt(fmt1
) != av_get_packed_sample_fmt(fmt2
);
380 return channel_count1
!= channel_count2
|| fmt1
!= fmt2
;
384 int64_t get_valid_channel_layout(int64_t channel_layout
, int channels
)
386 if (channel_layout
&& av_get_channel_layout_nb_channels(channel_layout
) == channels
)
387 return channel_layout
;
392 static void free_picture(Frame
*vp
);
394 static int packet_queue_put_private(PacketQueue
*q
, AVPacket
*pkt
)
396 MyAVPacketList
*pkt1
;
398 if (q
->abort_request
)
401 pkt1
= av_malloc(sizeof(MyAVPacketList
));
406 if (pkt
== &flush_pkt
)
408 pkt1
->serial
= q
->serial
;
413 q
->last_pkt
->next
= pkt1
;
416 q
->size
+= pkt1
->pkt
.size
+ sizeof(*pkt1
);
417 /* XXX: should duplicate packet data in DV case */
418 SDL_CondSignal(q
->cond
);
422 static int packet_queue_put(PacketQueue
*q
, AVPacket
*pkt
)
426 /* duplicate the packet */
427 if (pkt
!= &flush_pkt
&& av_dup_packet(pkt
) < 0)
430 SDL_LockMutex(q
->mutex
);
431 ret
= packet_queue_put_private(q
, pkt
);
432 SDL_UnlockMutex(q
->mutex
);
434 if (pkt
!= &flush_pkt
&& ret
< 0)
440 static int packet_queue_put_nullpacket(PacketQueue
*q
, int stream_index
)
442 AVPacket pkt1
, *pkt
= &pkt1
;
446 pkt
->stream_index
= stream_index
;
447 return packet_queue_put(q
, pkt
);
450 /* packet queue handling */
451 static void packet_queue_init(PacketQueue
*q
)
453 memset(q
, 0, sizeof(PacketQueue
));
454 q
->mutex
= SDL_CreateMutex();
455 q
->cond
= SDL_CreateCond();
456 q
->abort_request
= 1;
459 static void packet_queue_flush(PacketQueue
*q
)
461 MyAVPacketList
*pkt
, *pkt1
;
463 SDL_LockMutex(q
->mutex
);
464 for (pkt
= q
->first_pkt
; pkt
; pkt
= pkt1
) {
466 av_free_packet(&pkt
->pkt
);
473 SDL_UnlockMutex(q
->mutex
);
476 static void packet_queue_destroy(PacketQueue
*q
)
478 packet_queue_flush(q
);
479 SDL_DestroyMutex(q
->mutex
);
480 SDL_DestroyCond(q
->cond
);
483 static void packet_queue_abort(PacketQueue
*q
)
485 SDL_LockMutex(q
->mutex
);
487 q
->abort_request
= 1;
489 SDL_CondSignal(q
->cond
);
491 SDL_UnlockMutex(q
->mutex
);
494 static void packet_queue_start(PacketQueue
*q
)
496 SDL_LockMutex(q
->mutex
);
497 q
->abort_request
= 0;
498 packet_queue_put_private(q
, &flush_pkt
);
499 SDL_UnlockMutex(q
->mutex
);
502 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
503 static int packet_queue_get(PacketQueue
*q
, AVPacket
*pkt
, int block
, int *serial
)
505 MyAVPacketList
*pkt1
;
508 SDL_LockMutex(q
->mutex
);
511 if (q
->abort_request
) {
518 q
->first_pkt
= pkt1
->next
;
522 q
->size
-= pkt1
->pkt
.size
+ sizeof(*pkt1
);
525 *serial
= pkt1
->serial
;
533 SDL_CondWait(q
->cond
, q
->mutex
);
536 SDL_UnlockMutex(q
->mutex
);
540 static void decoder_init(Decoder
*d
, AVCodecContext
*avctx
, PacketQueue
*queue
, SDL_cond
*empty_queue_cond
) {
541 memset(d
, 0, sizeof(Decoder
));
544 d
->empty_queue_cond
= empty_queue_cond
;
545 d
->start_pts
= AV_NOPTS_VALUE
;
548 static int decoder_decode_frame(Decoder
*d
, AVFrame
*frame
, AVSubtitle
*sub
) {
556 if (d
->queue
->abort_request
)
559 if (!d
->packet_pending
|| d
->queue
->serial
!= d
->pkt_serial
) {
562 if (d
->queue
->nb_packets
== 0)
563 SDL_CondSignal(d
->empty_queue_cond
);
564 if (packet_queue_get(d
->queue
, &pkt
, 1, &d
->pkt_serial
) < 0)
566 if (pkt
.data
== flush_pkt
.data
) {
567 avcodec_flush_buffers(d
->avctx
);
570 d
->next_pts
= d
->start_pts
;
571 d
->next_pts_tb
= d
->start_pts_tb
;
573 } while (pkt
.data
== flush_pkt
.data
|| d
->queue
->serial
!= d
->pkt_serial
);
574 av_free_packet(&d
->pkt
);
575 d
->pkt_temp
= d
->pkt
= pkt
;
576 d
->packet_pending
= 1;
579 switch (d
->avctx
->codec_type
) {
580 case AVMEDIA_TYPE_VIDEO
:
581 ret
= avcodec_decode_video2(d
->avctx
, frame
, &got_frame
, &d
->pkt_temp
);
583 if (decoder_reorder_pts
== -1) {
584 frame
->pts
= av_frame_get_best_effort_timestamp(frame
);
585 } else if (decoder_reorder_pts
) {
586 frame
->pts
= frame
->pkt_pts
;
588 frame
->pts
= frame
->pkt_dts
;
592 case AVMEDIA_TYPE_AUDIO
:
593 ret
= avcodec_decode_audio4(d
->avctx
, frame
, &got_frame
, &d
->pkt_temp
);
595 AVRational tb
= (AVRational
){1, frame
->sample_rate
};
596 if (frame
->pts
!= AV_NOPTS_VALUE
)
597 frame
->pts
= av_rescale_q(frame
->pts
, d
->avctx
->time_base
, tb
);
598 else if (frame
->pkt_pts
!= AV_NOPTS_VALUE
)
599 frame
->pts
= av_rescale_q(frame
->pkt_pts
, av_codec_get_pkt_timebase(d
->avctx
), tb
);
600 else if (d
->next_pts
!= AV_NOPTS_VALUE
)
601 frame
->pts
= av_rescale_q(d
->next_pts
, d
->next_pts_tb
, tb
);
602 if (frame
->pts
!= AV_NOPTS_VALUE
) {
603 d
->next_pts
= frame
->pts
+ frame
->nb_samples
;
608 case AVMEDIA_TYPE_SUBTITLE
:
609 ret
= avcodec_decode_subtitle2(d
->avctx
, sub
, &got_frame
, &d
->pkt_temp
);
614 d
->packet_pending
= 0;
617 d
->pkt_temp
.pts
= AV_NOPTS_VALUE
;
618 if (d
->pkt_temp
.data
) {
619 if (d
->avctx
->codec_type
!= AVMEDIA_TYPE_AUDIO
)
620 ret
= d
->pkt_temp
.size
;
621 d
->pkt_temp
.data
+= ret
;
622 d
->pkt_temp
.size
-= ret
;
623 if (d
->pkt_temp
.size
<= 0)
624 d
->packet_pending
= 0;
627 d
->packet_pending
= 0;
628 d
->finished
= d
->pkt_serial
;
632 } while (!got_frame
&& !d
->finished
);
637 static void decoder_destroy(Decoder
*d
) {
638 av_free_packet(&d
->pkt
);
641 static void frame_queue_unref_item(Frame
*vp
)
643 av_frame_unref(vp
->frame
);
644 avsubtitle_free(&vp
->sub
);
647 static int frame_queue_init(FrameQueue
*f
, PacketQueue
*pktq
, int max_size
, int keep_last
)
650 memset(f
, 0, sizeof(FrameQueue
));
651 if (!(f
->mutex
= SDL_CreateMutex()))
652 return AVERROR(ENOMEM
);
653 if (!(f
->cond
= SDL_CreateCond()))
654 return AVERROR(ENOMEM
);
656 f
->max_size
= FFMIN(max_size
, FRAME_QUEUE_SIZE
);
657 f
->keep_last
= !!keep_last
;
658 for (i
= 0; i
< f
->max_size
; i
++)
659 if (!(f
->queue
[i
].frame
= av_frame_alloc()))
660 return AVERROR(ENOMEM
);
664 static void frame_queue_destory(FrameQueue
*f
)
667 for (i
= 0; i
< f
->max_size
; i
++) {
668 Frame
*vp
= &f
->queue
[i
];
669 frame_queue_unref_item(vp
);
670 av_frame_free(&vp
->frame
);
673 SDL_DestroyMutex(f
->mutex
);
674 SDL_DestroyCond(f
->cond
);
677 static void frame_queue_signal(FrameQueue
*f
)
679 SDL_LockMutex(f
->mutex
);
680 SDL_CondSignal(f
->cond
);
681 SDL_UnlockMutex(f
->mutex
);
684 static Frame
*frame_queue_peek(FrameQueue
*f
)
686 return &f
->queue
[(f
->rindex
+ f
->rindex_shown
) % f
->max_size
];
689 static Frame
*frame_queue_peek_next(FrameQueue
*f
)
691 return &f
->queue
[(f
->rindex
+ f
->rindex_shown
+ 1) % f
->max_size
];
694 static Frame
*frame_queue_peek_last(FrameQueue
*f
)
696 return &f
->queue
[f
->rindex
];
699 static Frame
*frame_queue_peek_writable(FrameQueue
*f
)
701 /* wait until we have space to put a new frame */
702 SDL_LockMutex(f
->mutex
);
703 while (f
->size
>= f
->max_size
&&
704 !f
->pktq
->abort_request
) {
705 SDL_CondWait(f
->cond
, f
->mutex
);
707 SDL_UnlockMutex(f
->mutex
);
709 if (f
->pktq
->abort_request
)
712 return &f
->queue
[f
->windex
];
715 static Frame
*frame_queue_peek_readable(FrameQueue
*f
)
717 /* wait until we have a readable a new frame */
718 SDL_LockMutex(f
->mutex
);
719 while (f
->size
- f
->rindex_shown
<= 0 &&
720 !f
->pktq
->abort_request
) {
721 SDL_CondWait(f
->cond
, f
->mutex
);
723 SDL_UnlockMutex(f
->mutex
);
725 if (f
->pktq
->abort_request
)
728 return &f
->queue
[(f
->rindex
+ f
->rindex_shown
) % f
->max_size
];
731 static void frame_queue_push(FrameQueue
*f
)
733 if (++f
->windex
== f
->max_size
)
735 SDL_LockMutex(f
->mutex
);
737 SDL_CondSignal(f
->cond
);
738 SDL_UnlockMutex(f
->mutex
);
741 static void frame_queue_next(FrameQueue
*f
)
743 if (f
->keep_last
&& !f
->rindex_shown
) {
747 frame_queue_unref_item(&f
->queue
[f
->rindex
]);
748 if (++f
->rindex
== f
->max_size
)
750 SDL_LockMutex(f
->mutex
);
752 SDL_CondSignal(f
->cond
);
753 SDL_UnlockMutex(f
->mutex
);
756 /* jump back to the previous frame if available by resetting rindex_shown */
757 static int frame_queue_prev(FrameQueue
*f
)
759 int ret
= f
->rindex_shown
;
764 /* return the number of undisplayed frames in the queue */
765 static int frame_queue_nb_remaining(FrameQueue
*f
)
767 return f
->size
- f
->rindex_shown
;
770 /* return last shown position */
771 static int64_t frame_queue_last_pos(FrameQueue
*f
)
773 Frame
*fp
= &f
->queue
[f
->rindex
];
774 if (f
->rindex_shown
&& fp
->serial
== f
->pktq
->serial
)
780 static inline void fill_rectangle(SDL_Surface
*screen
,
781 int x
, int y
, int w
, int h
, int color
, int update
)
788 SDL_FillRect(screen
, &rect
, color
);
789 if (update
&& w
> 0 && h
> 0)
790 SDL_UpdateRect(screen
, x
, y
, w
, h
);
793 /* draw only the border of a rectangle */
794 static void fill_border(int xleft
, int ytop
, int width
, int height
, int x
, int y
, int w
, int h
, int color
, int update
)
798 /* fill the background */
802 w2
= width
- (x
+ w
);
808 h2
= height
- (y
+ h
);
811 fill_rectangle(screen
,
815 fill_rectangle(screen
,
816 xleft
+ width
- w2
, ytop
,
819 fill_rectangle(screen
,
823 fill_rectangle(screen
,
824 xleft
+ w1
, ytop
+ height
- h2
,
829 #define ALPHA_BLEND(a, oldp, newp, s)\
830 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
832 #define RGBA_IN(r, g, b, a, s)\
834 unsigned int v = ((const uint32_t *)(s))[0];\
835 a = (v >> 24) & 0xff;\
836 r = (v >> 16) & 0xff;\
837 g = (v >> 8) & 0xff;\
841 #define YUVA_IN(y, u, v, a, s, pal)\
843 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
844 a = (val >> 24) & 0xff;\
845 y = (val >> 16) & 0xff;\
846 u = (val >> 8) & 0xff;\
850 #define YUVA_OUT(d, y, u, v, a)\
852 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
858 static void blend_subrect(AVPicture
*dst
, const AVSubtitleRect
*rect
, int imgw
, int imgh
)
860 int wrap
, wrap3
, width2
, skip2
;
861 int y
, u
, v
, a
, u1
, v1
, a1
, w
, h
;
862 uint8_t *lum
, *cb
, *cr
;
865 int dstx
, dsty
, dstw
, dsth
;
867 dstw
= av_clip(rect
->w
, 0, imgw
);
868 dsth
= av_clip(rect
->h
, 0, imgh
);
869 dstx
= av_clip(rect
->x
, 0, imgw
- dstw
);
870 dsty
= av_clip(rect
->y
, 0, imgh
- dsth
);
871 lum
= dst
->data
[0] + dsty
* dst
->linesize
[0];
872 cb
= dst
->data
[1] + (dsty
>> 1) * dst
->linesize
[1];
873 cr
= dst
->data
[2] + (dsty
>> 1) * dst
->linesize
[2];
875 width2
= ((dstw
+ 1) >> 1) + (dstx
& ~dstw
& 1);
877 wrap
= dst
->linesize
[0];
878 wrap3
= rect
->pict
.linesize
[0];
879 p
= rect
->pict
.data
[0];
880 pal
= (const uint32_t *)rect
->pict
.data
[1]; /* Now in YCrCb! */
888 YUVA_IN(y
, u
, v
, a
, p
, pal
);
889 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
890 cb
[0] = ALPHA_BLEND(a
>> 2, cb
[0], u
, 0);
891 cr
[0] = ALPHA_BLEND(a
>> 2, cr
[0], v
, 0);
897 for (w
= dstw
- (dstx
& 1); w
>= 2; w
-= 2) {
898 YUVA_IN(y
, u
, v
, a
, p
, pal
);
902 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
904 YUVA_IN(y
, u
, v
, a
, p
+ BPP
, pal
);
908 lum
[1] = ALPHA_BLEND(a
, lum
[1], y
, 0);
909 cb
[0] = ALPHA_BLEND(a1
>> 2, cb
[0], u1
, 1);
910 cr
[0] = ALPHA_BLEND(a1
>> 2, cr
[0], v1
, 1);
917 YUVA_IN(y
, u
, v
, a
, p
, pal
);
918 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
919 cb
[0] = ALPHA_BLEND(a
>> 2, cb
[0], u
, 0);
920 cr
[0] = ALPHA_BLEND(a
>> 2, cr
[0], v
, 0);
924 p
+= wrap3
- dstw
* BPP
;
925 lum
+= wrap
- dstw
- dstx
;
926 cb
+= dst
->linesize
[1] - width2
- skip2
;
927 cr
+= dst
->linesize
[2] - width2
- skip2
;
929 for (h
= dsth
- (dsty
& 1); h
>= 2; h
-= 2) {
935 YUVA_IN(y
, u
, v
, a
, p
, pal
);
939 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
942 YUVA_IN(y
, u
, v
, a
, p
, pal
);
946 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
947 cb
[0] = ALPHA_BLEND(a1
>> 2, cb
[0], u1
, 1);
948 cr
[0] = ALPHA_BLEND(a1
>> 2, cr
[0], v1
, 1);
954 for (w
= dstw
- (dstx
& 1); w
>= 2; w
-= 2) {
955 YUVA_IN(y
, u
, v
, a
, p
, pal
);
959 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
961 YUVA_IN(y
, u
, v
, a
, p
+ BPP
, pal
);
965 lum
[1] = ALPHA_BLEND(a
, lum
[1], y
, 0);
969 YUVA_IN(y
, u
, v
, a
, p
, pal
);
973 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
975 YUVA_IN(y
, u
, v
, a
, p
+ BPP
, pal
);
979 lum
[1] = ALPHA_BLEND(a
, lum
[1], y
, 0);
981 cb
[0] = ALPHA_BLEND(a1
>> 2, cb
[0], u1
, 2);
982 cr
[0] = ALPHA_BLEND(a1
>> 2, cr
[0], v1
, 2);
986 p
+= -wrap3
+ 2 * BPP
;
990 YUVA_IN(y
, u
, v
, a
, p
, pal
);
994 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
997 YUVA_IN(y
, u
, v
, a
, p
, pal
);
1001 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
1002 cb
[0] = ALPHA_BLEND(a1
>> 2, cb
[0], u1
, 1);
1003 cr
[0] = ALPHA_BLEND(a1
>> 2, cr
[0], v1
, 1);
1009 p
+= wrap3
+ (wrap3
- dstw
* BPP
);
1010 lum
+= wrap
+ (wrap
- dstw
- dstx
);
1011 cb
+= dst
->linesize
[1] - width2
- skip2
;
1012 cr
+= dst
->linesize
[2] - width2
- skip2
;
1014 /* handle odd height */
1021 YUVA_IN(y
, u
, v
, a
, p
, pal
);
1022 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
1023 cb
[0] = ALPHA_BLEND(a
>> 2, cb
[0], u
, 0);
1024 cr
[0] = ALPHA_BLEND(a
>> 2, cr
[0], v
, 0);
1030 for (w
= dstw
- (dstx
& 1); w
>= 2; w
-= 2) {
1031 YUVA_IN(y
, u
, v
, a
, p
, pal
);
1035 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
1037 YUVA_IN(y
, u
, v
, a
, p
+ BPP
, pal
);
1041 lum
[1] = ALPHA_BLEND(a
, lum
[1], y
, 0);
1042 cb
[0] = ALPHA_BLEND(a1
>> 2, cb
[0], u
, 1);
1043 cr
[0] = ALPHA_BLEND(a1
>> 2, cr
[0], v
, 1);
1050 YUVA_IN(y
, u
, v
, a
, p
, pal
);
1051 lum
[0] = ALPHA_BLEND(a
, lum
[0], y
, 0);
1052 cb
[0] = ALPHA_BLEND(a
>> 2, cb
[0], u
, 0);
1053 cr
[0] = ALPHA_BLEND(a
>> 2, cr
[0], v
, 0);
1058 static void free_picture(Frame
*vp
)
1061 SDL_FreeYUVOverlay(vp
->bmp
);
1066 static void calculate_display_rect(SDL_Rect
*rect
,
1067 int scr_xleft
, int scr_ytop
, int scr_width
, int scr_height
,
1068 int pic_width
, int pic_height
, AVRational pic_sar
)
1071 int width
, height
, x
, y
;
1073 if (pic_sar
.num
== 0)
1076 aspect_ratio
= av_q2d(pic_sar
);
1078 if (aspect_ratio
<= 0.0)
1080 aspect_ratio
*= (float)pic_width
/ (float)pic_height
;
1082 /* XXX: we suppose the screen has a 1.0 pixel ratio */
1083 height
= scr_height
;
1084 width
= ((int)rint(height
* aspect_ratio
)) & ~1;
1085 if (width
> scr_width
) {
1087 height
= ((int)rint(width
/ aspect_ratio
)) & ~1;
1089 x
= (scr_width
- width
) / 2;
1090 y
= (scr_height
- height
) / 2;
1091 rect
->x
= scr_xleft
+ x
;
1092 rect
->y
= scr_ytop
+ y
;
1093 rect
->w
= FFMAX(width
, 1);
1094 rect
->h
= FFMAX(height
, 1);
1097 static void video_image_display(VideoState
*is
)
1105 vp
= frame_queue_peek(&is
->pictq
);
1107 if (is
->subtitle_st
) {
1108 if (frame_queue_nb_remaining(&is
->subpq
) > 0) {
1109 sp
= frame_queue_peek(&is
->subpq
);
1111 if (vp
->pts
>= sp
->pts
+ ((float) sp
->sub
.start_display_time
/ 1000)) {
1112 SDL_LockYUVOverlay (vp
->bmp
);
1114 pict
.data
[0] = vp
->bmp
->pixels
[0];
1115 pict
.data
[1] = vp
->bmp
->pixels
[2];
1116 pict
.data
[2] = vp
->bmp
->pixels
[1];
1118 pict
.linesize
[0] = vp
->bmp
->pitches
[0];
1119 pict
.linesize
[1] = vp
->bmp
->pitches
[2];
1120 pict
.linesize
[2] = vp
->bmp
->pitches
[1];
1122 for (i
= 0; i
< sp
->sub
.num_rects
; i
++)
1123 blend_subrect(&pict
, sp
->sub
.rects
[i
],
1124 vp
->bmp
->w
, vp
->bmp
->h
);
1126 SDL_UnlockYUVOverlay (vp
->bmp
);
1131 calculate_display_rect(&rect
, is
->xleft
, is
->ytop
, is
->width
, is
->height
, vp
->width
, vp
->height
, vp
->sar
);
1133 SDL_DisplayYUVOverlay(vp
->bmp
, &rect
);
1135 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
) {
1136 int bgcolor
= SDL_MapRGB(screen
->format
, 0x00, 0x00, 0x00);
1137 fill_border(is
->xleft
, is
->ytop
, is
->width
, is
->height
, rect
.x
, rect
.y
, rect
.w
, rect
.h
, bgcolor
, 1);
1138 is
->last_display_rect
= rect
;
1143 static inline int compute_mod(int a
, int b
)
1145 return a
< 0 ? a%b
+ b
: a%b
;
1148 static void video_audio_display(VideoState
*s
)
1150 int i
, i_start
, x
, y1
, y
, ys
, delay
, n
, nb_display_channels
;
1151 int ch
, channels
, h
, h2
, bgcolor
, fgcolor
;
1153 int rdft_bits
, nb_freq
;
1155 for (rdft_bits
= 1; (1 << rdft_bits
) < 2 * s
->height
; rdft_bits
++)
1157 nb_freq
= 1 << (rdft_bits
- 1);
1159 /* compute display index : center on currently output samples */
1160 channels
= s
->audio_tgt
.channels
;
1161 nb_display_channels
= channels
;
1163 int data_used
= s
->show_mode
== SHOW_MODE_WAVES
? s
->width
: (2*nb_freq
);
1165 delay
= s
->audio_write_buf_size
;
1168 /* to be more precise, we take into account the time spent since
1169 the last buffer computation */
1170 if (audio_callback_time
) {
1171 time_diff
= av_gettime_relative() - audio_callback_time
;
1172 delay
-= (time_diff
* s
->audio_tgt
.freq
) / 1000000;
1175 delay
+= 2 * data_used
;
1176 if (delay
< data_used
)
1179 i_start
= x
= compute_mod(s
->sample_array_index
- delay
* channels
, SAMPLE_ARRAY_SIZE
);
1180 if (s
->show_mode
== SHOW_MODE_WAVES
) {
1182 for (i
= 0; i
< 1000; i
+= channels
) {
1183 int idx
= (SAMPLE_ARRAY_SIZE
+ x
- i
) % SAMPLE_ARRAY_SIZE
;
1184 int a
= s
->sample_array
[idx
];
1185 int b
= s
->sample_array
[(idx
+ 4 * channels
) % SAMPLE_ARRAY_SIZE
];
1186 int c
= s
->sample_array
[(idx
+ 5 * channels
) % SAMPLE_ARRAY_SIZE
];
1187 int d
= s
->sample_array
[(idx
+ 9 * channels
) % SAMPLE_ARRAY_SIZE
];
1189 if (h
< score
&& (b
^ c
) < 0) {
1196 s
->last_i_start
= i_start
;
1198 i_start
= s
->last_i_start
;
1201 bgcolor
= SDL_MapRGB(screen
->format
, 0x00, 0x00, 0x00);
1202 if (s
->show_mode
== SHOW_MODE_WAVES
) {
1203 fill_rectangle(screen
,
1204 s
->xleft
, s
->ytop
, s
->width
, s
->height
,
1207 fgcolor
= SDL_MapRGB(screen
->format
, 0xff, 0xff, 0xff);
1209 /* total height for one channel */
1210 h
= s
->height
/ nb_display_channels
;
1211 /* graph height / 2 */
1213 for (ch
= 0; ch
< nb_display_channels
; ch
++) {
1215 y1
= s
->ytop
+ ch
* h
+ (h
/ 2); /* position of center line */
1216 for (x
= 0; x
< s
->width
; x
++) {
1217 y
= (s
->sample_array
[i
] * h2
) >> 15;
1224 fill_rectangle(screen
,
1225 s
->xleft
+ x
, ys
, 1, y
,
1228 if (i
>= SAMPLE_ARRAY_SIZE
)
1229 i
-= SAMPLE_ARRAY_SIZE
;
1233 fgcolor
= SDL_MapRGB(screen
->format
, 0x00, 0x00, 0xff);
1235 for (ch
= 1; ch
< nb_display_channels
; ch
++) {
1236 y
= s
->ytop
+ ch
* h
;
1237 fill_rectangle(screen
,
1238 s
->xleft
, y
, s
->width
, 1,
1241 SDL_UpdateRect(screen
, s
->xleft
, s
->ytop
, s
->width
, s
->height
);
1243 nb_display_channels
= FFMIN(nb_display_channels
, 2);
1244 if (rdft_bits
!= s
->rdft_bits
) {
1245 av_rdft_end(s
->rdft
);
1246 av_free(s
->rdft_data
);
1247 s
->rdft
= av_rdft_init(rdft_bits
, DFT_R2C
);
1248 s
->rdft_bits
= rdft_bits
;
1249 s
->rdft_data
= av_malloc_array(nb_freq
, 4 *sizeof(*s
->rdft_data
));
1253 for (ch
= 0; ch
< nb_display_channels
; ch
++) {
1254 data
[ch
] = s
->rdft_data
+ 2 * nb_freq
* ch
;
1256 for (x
= 0; x
< 2 * nb_freq
; x
++) {
1257 double w
= (x
-nb_freq
) * (1.0 / nb_freq
);
1258 data
[ch
][x
] = s
->sample_array
[i
] * (1.0 - w
* w
);
1260 if (i
>= SAMPLE_ARRAY_SIZE
)
1261 i
-= SAMPLE_ARRAY_SIZE
;
1263 av_rdft_calc(s
->rdft
, data
[ch
]);
1265 /* Least efficient way to do this, we should of course
1266 * directly access it but it is more than fast enough. */
1267 for (y
= 0; y
< s
->height
; y
++) {
1268 double w
= 1 / sqrt(nb_freq
);
1269 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]));
1270 int b
= (nb_display_channels
== 2 ) ? sqrt(w
* sqrt(data
[1][2 * y
+ 0] * data
[1][2 * y
+ 0]
1271 + data
[1][2 * y
+ 1] * data
[1][2 * y
+ 1])) : a
;
1274 fgcolor
= SDL_MapRGB(screen
->format
, a
, b
, (a
+ b
) / 2);
1276 fill_rectangle(screen
,
1277 s
->xpos
, s
->height
-y
, 1, 1,
1281 SDL_UpdateRect(screen
, s
->xpos
, s
->ytop
, 1, s
->height
);
1284 if (s
->xpos
>= s
->width
)
1289 static void stream_close(VideoState
*is
)
1291 /* XXX: use a special url_shutdown call to abort parse cleanly */
1292 is
->abort_request
= 1;
1293 SDL_WaitThread(is
->read_tid
, NULL
);
1294 packet_queue_destroy(&is
->videoq
);
1295 packet_queue_destroy(&is
->audioq
);
1296 packet_queue_destroy(&is
->subtitleq
);
1298 /* free all pictures */
1299 frame_queue_destory(&is
->pictq
);
1300 frame_queue_destory(&is
->sampq
);
1301 frame_queue_destory(&is
->subpq
);
1302 SDL_DestroyCond(is
->continue_read_thread
);
1303 #if !CONFIG_AVFILTER
1304 sws_freeContext(is
->img_convert_ctx
);
1309 static void do_exit(VideoState
*is
)
1314 av_lockmgr_register(NULL
);
1317 av_freep(&vfilters_list
);
1319 avformat_network_deinit();
1323 av_log(NULL
, AV_LOG_QUIET
, "%s", "");
1327 static void sigterm_handler(int sig
)
1332 static void set_default_window_size(int width
, int height
, AVRational sar
)
1335 calculate_display_rect(&rect
, 0, 0, INT_MAX
, height
, width
, height
, sar
);
1336 default_width
= rect
.w
;
1337 default_height
= rect
.h
;
1340 static int video_open(VideoState
*is
, int force_set_video_mode
, Frame
*vp
)
1342 int flags
= SDL_HWSURFACE
| SDL_ASYNCBLIT
| SDL_HWACCEL
;
1345 if (is_full_screen
) flags
|= SDL_FULLSCREEN
;
1346 else flags
|= SDL_RESIZABLE
;
1348 if (vp
&& vp
->width
)
1349 set_default_window_size(vp
->width
, vp
->height
, vp
->sar
);
1351 if (is_full_screen
&& fs_screen_width
) {
1352 w
= fs_screen_width
;
1353 h
= fs_screen_height
;
1354 } else if (!is_full_screen
&& screen_width
) {
1361 w
= FFMIN(16383, w
);
1362 if (screen
&& is
->width
== screen
->w
&& screen
->w
== w
1363 && is
->height
== screen
->h
&& screen
->h
== h
&& !force_set_video_mode
)
1365 screen
= SDL_SetVideoMode(w
, h
, 0, flags
);
1367 av_log(NULL
, AV_LOG_FATAL
, "SDL: could not set video mode - exiting\n");
1371 window_title
= input_filename
;
1372 SDL_WM_SetCaption(window_title
, window_title
);
1374 is
->width
= screen
->w
;
1375 is
->height
= screen
->h
;
1380 /* display the current picture, if any */
1381 static void video_display(VideoState
*is
)
1384 video_open(is
, 0, NULL
);
1385 if (is
->audio_st
&& is
->show_mode
!= SHOW_MODE_VIDEO
)
1386 video_audio_display(is
);
1387 else if (is
->video_st
)
1388 video_image_display(is
);
1391 static double get_clock(Clock
*c
)
1393 if (*c
->queue_serial
!= c
->serial
)
1398 double time
= av_gettime_relative() / 1000000.0;
1399 return c
->pts_drift
+ time
- (time
- c
->last_updated
) * (1.0 - c
->speed
);
1403 static void set_clock_at(Clock
*c
, double pts
, int serial
, double time
)
1406 c
->last_updated
= time
;
1407 c
->pts_drift
= c
->pts
- time
;
1411 static void set_clock(Clock
*c
, double pts
, int serial
)
1413 double time
= av_gettime_relative() / 1000000.0;
1414 set_clock_at(c
, pts
, serial
, time
);
1417 static void set_clock_speed(Clock
*c
, double speed
)
1419 set_clock(c
, get_clock(c
), c
->serial
);
1423 static void init_clock(Clock
*c
, int *queue_serial
)
1427 c
->queue_serial
= queue_serial
;
1428 set_clock(c
, NAN
, -1);
1431 static void sync_clock_to_slave(Clock
*c
, Clock
*slave
)
1433 double clock
= get_clock(c
);
1434 double slave_clock
= get_clock(slave
);
1435 if (!isnan(slave_clock
) && (isnan(clock
) || fabs(clock
- slave_clock
) > AV_NOSYNC_THRESHOLD
))
1436 set_clock(c
, slave_clock
, slave
->serial
);
1439 static int get_master_sync_type(VideoState
*is
) {
1440 if (is
->av_sync_type
== AV_SYNC_VIDEO_MASTER
) {
1442 return AV_SYNC_VIDEO_MASTER
;
1444 return AV_SYNC_AUDIO_MASTER
;
1445 } else if (is
->av_sync_type
== AV_SYNC_AUDIO_MASTER
) {
1447 return AV_SYNC_AUDIO_MASTER
;
1449 return AV_SYNC_EXTERNAL_CLOCK
;
1451 return AV_SYNC_EXTERNAL_CLOCK
;
1455 /* get the current master clock value */
1456 static double get_master_clock(VideoState
*is
)
1460 switch (get_master_sync_type(is
)) {
1461 case AV_SYNC_VIDEO_MASTER
:
1462 val
= get_clock(&is
->vidclk
);
1464 case AV_SYNC_AUDIO_MASTER
:
1465 val
= get_clock(&is
->audclk
);
1468 val
= get_clock(&is
->extclk
);
1474 static void check_external_clock_speed(VideoState
*is
) {
1475 if (is
->video_stream
>= 0 && is
->videoq
.nb_packets
<= MIN_FRAMES
/ 2 ||
1476 is
->audio_stream
>= 0 && is
->audioq
.nb_packets
<= MIN_FRAMES
/ 2) {
1477 set_clock_speed(&is
->extclk
, FFMAX(EXTERNAL_CLOCK_SPEED_MIN
, is
->extclk
.speed
- EXTERNAL_CLOCK_SPEED_STEP
));
1478 } else if ((is
->video_stream
< 0 || is
->videoq
.nb_packets
> MIN_FRAMES
* 2) &&
1479 (is
->audio_stream
< 0 || is
->audioq
.nb_packets
> MIN_FRAMES
* 2)) {
1480 set_clock_speed(&is
->extclk
, FFMIN(EXTERNAL_CLOCK_SPEED_MAX
, is
->extclk
.speed
+ EXTERNAL_CLOCK_SPEED_STEP
));
1482 double speed
= is
->extclk
.speed
;
1484 set_clock_speed(&is
->extclk
, speed
+ EXTERNAL_CLOCK_SPEED_STEP
* (1.0 - speed
) / fabs(1.0 - speed
));
1488 /* seek in the stream */
1489 static void stream_seek(VideoState
*is
, int64_t pos
, int64_t rel
, int seek_by_bytes
)
1491 if (!is
->seek_req
) {
1494 is
->seek_flags
&= ~AVSEEK_FLAG_BYTE
;
1496 is
->seek_flags
|= AVSEEK_FLAG_BYTE
;
1498 SDL_CondSignal(is
->continue_read_thread
);
1502 /* pause or resume the video */
1503 static void stream_toggle_pause(VideoState
*is
)
1506 is
->frame_timer
+= av_gettime_relative() / 1000000.0 + is
->vidclk
.pts_drift
- is
->vidclk
.pts
;
1507 if (is
->read_pause_return
!= AVERROR(ENOSYS
)) {
1508 is
->vidclk
.paused
= 0;
1510 set_clock(&is
->vidclk
, get_clock(&is
->vidclk
), is
->vidclk
.serial
);
1512 set_clock(&is
->extclk
, get_clock(&is
->extclk
), is
->extclk
.serial
);
1513 is
->paused
= is
->audclk
.paused
= is
->vidclk
.paused
= is
->extclk
.paused
= !is
->paused
;
1516 static void toggle_pause(VideoState
*is
)
1518 stream_toggle_pause(is
);
1522 static void step_to_next_frame(VideoState
*is
)
1524 /* if the stream is paused unpause it, then step */
1526 stream_toggle_pause(is
);
1530 static double compute_target_delay(double delay
, VideoState
*is
)
1532 double sync_threshold
, diff
;
1534 /* update delay to follow master synchronisation source */
1535 if (get_master_sync_type(is
) != AV_SYNC_VIDEO_MASTER
) {
1536 /* if video is slave, we try to correct big delays by
1537 duplicating or deleting a frame */
1538 diff
= get_clock(&is
->vidclk
) - get_master_clock(is
);
1540 /* skip or repeat frame. We take into account the
1541 delay to compute the threshold. I still don't know
1542 if it is the best guess */
1543 sync_threshold
= FFMAX(AV_SYNC_THRESHOLD_MIN
, FFMIN(AV_SYNC_THRESHOLD_MAX
, delay
));
1544 if (!isnan(diff
) && fabs(diff
) < is
->max_frame_duration
) {
1545 if (diff
<= -sync_threshold
)
1546 delay
= FFMAX(0, delay
+ diff
);
1547 else if (diff
>= sync_threshold
&& delay
> AV_SYNC_FRAMEDUP_THRESHOLD
)
1548 delay
= delay
+ diff
;
1549 else if (diff
>= sync_threshold
)
1554 av_dlog(NULL
, "video: delay=%0.3f A-V=%f\n",
1560 static double vp_duration(VideoState
*is
, Frame
*vp
, Frame
*nextvp
) {
1561 if (vp
->serial
== nextvp
->serial
) {
1562 double duration
= nextvp
->pts
- vp
->pts
;
1563 if (isnan(duration
) || duration
<= 0 || duration
> is
->max_frame_duration
)
1564 return vp
->duration
;
1572 static void update_video_pts(VideoState
*is
, double pts
, int64_t pos
, int serial
) {
1573 /* update current video pts */
1574 set_clock(&is
->vidclk
, pts
, serial
);
1575 sync_clock_to_slave(&is
->extclk
, &is
->vidclk
);
1578 /* called to display each frame */
1579 static void video_refresh(void *opaque
, double *remaining_time
)
1581 VideoState
*is
= opaque
;
1586 if (!is
->paused
&& get_master_sync_type(is
) == AV_SYNC_EXTERNAL_CLOCK
&& is
->realtime
)
1587 check_external_clock_speed(is
);
1589 if (!display_disable
&& is
->show_mode
!= SHOW_MODE_VIDEO
&& is
->audio_st
) {
1590 time
= av_gettime_relative() / 1000000.0;
1591 if (is
->force_refresh
|| is
->last_vis_time
+ rdftspeed
< time
) {
1593 is
->last_vis_time
= time
;
1595 *remaining_time
= FFMIN(*remaining_time
, is
->last_vis_time
+ rdftspeed
- time
);
1600 if (is
->force_refresh
)
1601 redisplay
= frame_queue_prev(&is
->pictq
);
1603 if (frame_queue_nb_remaining(&is
->pictq
) == 0) {
1604 // nothing to do, no picture to display in the queue
1606 double last_duration
, duration
, delay
;
1609 /* dequeue the picture */
1610 lastvp
= frame_queue_peek_last(&is
->pictq
);
1611 vp
= frame_queue_peek(&is
->pictq
);
1613 if (vp
->serial
!= is
->videoq
.serial
) {
1614 frame_queue_next(&is
->pictq
);
1619 if (lastvp
->serial
!= vp
->serial
&& !redisplay
)
1620 is
->frame_timer
= av_gettime_relative() / 1000000.0;
1625 /* compute nominal last_duration */
1626 last_duration
= vp_duration(is
, lastvp
, vp
);
1630 delay
= compute_target_delay(last_duration
, is
);
1632 time
= av_gettime_relative()/1000000.0;
1633 if (time
< is
->frame_timer
+ delay
&& !redisplay
) {
1634 *remaining_time
= FFMIN(is
->frame_timer
+ delay
- time
, *remaining_time
);
1638 is
->frame_timer
+= delay
;
1639 if (delay
> 0 && time
- is
->frame_timer
> AV_SYNC_THRESHOLD_MAX
)
1640 is
->frame_timer
= time
;
1642 SDL_LockMutex(is
->pictq
.mutex
);
1643 if (!redisplay
&& !isnan(vp
->pts
))
1644 update_video_pts(is
, vp
->pts
, vp
->pos
, vp
->serial
);
1645 SDL_UnlockMutex(is
->pictq
.mutex
);
1647 if (frame_queue_nb_remaining(&is
->pictq
) > 1) {
1648 Frame
*nextvp
= frame_queue_peek_next(&is
->pictq
);
1649 duration
= vp_duration(is
, vp
, nextvp
);
1650 if(!is
->step
&& (redisplay
|| framedrop
>0 || (framedrop
&& get_master_sync_type(is
) != AV_SYNC_VIDEO_MASTER
)) && time
> is
->frame_timer
+ duration
){
1652 is
->frame_drops_late
++;
1653 frame_queue_next(&is
->pictq
);
1659 if (is
->subtitle_st
) {
1660 while (frame_queue_nb_remaining(&is
->subpq
) > 0) {
1661 sp
= frame_queue_peek(&is
->subpq
);
1663 if (frame_queue_nb_remaining(&is
->subpq
) > 1)
1664 sp2
= frame_queue_peek_next(&is
->subpq
);
1668 if (sp
->serial
!= is
->subtitleq
.serial
1669 || (is
->vidclk
.pts
> (sp
->pts
+ ((float) sp
->sub
.end_display_time
/ 1000)))
1670 || (sp2
&& is
->vidclk
.pts
> (sp2
->pts
+ ((float) sp2
->sub
.start_display_time
/ 1000))))
1672 frame_queue_next(&is
->subpq
);
1680 /* display picture */
1681 if (!display_disable
&& is
->show_mode
== SHOW_MODE_VIDEO
)
1684 frame_queue_next(&is
->pictq
);
1686 if (is
->step
&& !is
->paused
)
1687 stream_toggle_pause(is
);
1690 is
->force_refresh
= 0;
1692 static int64_t last_time
;
1694 int aqsize
, vqsize
, sqsize
;
1697 cur_time
= av_gettime_relative();
1698 if (!last_time
|| (cur_time
- last_time
) >= 30000) {
1703 aqsize
= is
->audioq
.size
;
1705 vqsize
= is
->videoq
.size
;
1706 if (is
->subtitle_st
)
1707 sqsize
= is
->subtitleq
.size
;
1709 if (is
->audio_st
&& is
->video_st
)
1710 av_diff
= get_clock(&is
->audclk
) - get_clock(&is
->vidclk
);
1711 else if (is
->video_st
)
1712 av_diff
= get_master_clock(is
) - get_clock(&is
->vidclk
);
1713 else if (is
->audio_st
)
1714 av_diff
= get_master_clock(is
) - get_clock(&is
->audclk
);
1715 av_log(NULL
, AV_LOG_INFO
,
1716 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64
"/%"PRId64
" \r",
1717 get_master_clock(is
),
1718 (is
->audio_st
&& is
->video_st
) ? "A-V" : (is
->video_st
? "M-V" : (is
->audio_st
? "M-A" : " ")),
1720 is
->frame_drops_early
+ is
->frame_drops_late
,
1724 is
->video_st
? is
->video_st
->codec
->pts_correction_num_faulty_dts
: 0,
1725 is
->video_st
? is
->video_st
->codec
->pts_correction_num_faulty_pts
: 0);
1727 last_time
= cur_time
;
1732 /* allocate a picture (needs to do that in main thread to avoid
1733 potential locking problems */
1734 static void alloc_picture(VideoState
*is
)
1739 vp
= &is
->pictq
.queue
[is
->pictq
.windex
];
1743 video_open(is
, 0, vp
);
1745 vp
->bmp
= SDL_CreateYUVOverlay(vp
->width
, vp
->height
,
1748 bufferdiff
= vp
->bmp
? FFMAX(vp
->bmp
->pixels
[0], vp
->bmp
->pixels
[1]) - FFMIN(vp
->bmp
->pixels
[0], vp
->bmp
->pixels
[1]) : 0;
1749 if (!vp
->bmp
|| vp
->bmp
->pitches
[0] < vp
->width
|| bufferdiff
< (int64_t)vp
->height
* vp
->bmp
->pitches
[0]) {
1750 /* SDL allocates a buffer smaller than requested if the video
1751 * overlay hardware is unable to support the requested size. */
1752 av_log(NULL
, AV_LOG_FATAL
,
1753 "Error: the video system does not support an image\n"
1754 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1755 "to reduce the image size.\n", vp
->width
, vp
->height
);
1759 SDL_LockMutex(is
->pictq
.mutex
);
1761 SDL_CondSignal(is
->pictq
.cond
);
1762 SDL_UnlockMutex(is
->pictq
.mutex
);
1765 static void duplicate_right_border_pixels(SDL_Overlay
*bmp
) {
1766 int i
, width
, height
;
1768 for (i
= 0; i
< 3; i
++) {
1775 if (bmp
->pitches
[i
] > width
) {
1776 maxp
= bmp
->pixels
[i
] + bmp
->pitches
[i
] * height
- 1;
1777 for (p
= bmp
->pixels
[i
] + width
- 1; p
< maxp
; p
+= bmp
->pitches
[i
])
1783 static int queue_picture(VideoState
*is
, AVFrame
*src_frame
, double pts
, double duration
, int64_t pos
, int serial
)
1787 #if defined(DEBUG_SYNC) && 0
1788 printf("frame_type=%c pts=%0.3f\n",
1789 av_get_picture_type_char(src_frame
->pict_type
), pts
);
1792 if (!(vp
= frame_queue_peek_writable(&is
->pictq
)))
1795 vp
->sar
= src_frame
->sample_aspect_ratio
;
1797 /* alloc or resize hardware picture buffer */
1798 if (!vp
->bmp
|| vp
->reallocate
|| !vp
->allocated
||
1799 vp
->width
!= src_frame
->width
||
1800 vp
->height
!= src_frame
->height
) {
1805 vp
->width
= src_frame
->width
;
1806 vp
->height
= src_frame
->height
;
1808 /* the allocation must be done in the main thread to avoid
1809 locking problems. */
1810 event
.type
= FF_ALLOC_EVENT
;
1811 event
.user
.data1
= is
;
1812 SDL_PushEvent(&event
);
1814 /* wait until the picture is allocated */
1815 SDL_LockMutex(is
->pictq
.mutex
);
1816 while (!vp
->allocated
&& !is
->videoq
.abort_request
) {
1817 SDL_CondWait(is
->pictq
.cond
, is
->pictq
.mutex
);
1819 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1820 if (is
->videoq
.abort_request
&& SDL_PeepEvents(&event
, 1, SDL_GETEVENT
, SDL_EVENTMASK(FF_ALLOC_EVENT
)) != 1) {
1821 while (!vp
->allocated
&& !is
->abort_request
) {
1822 SDL_CondWait(is
->pictq
.cond
, is
->pictq
.mutex
);
1825 SDL_UnlockMutex(is
->pictq
.mutex
);
1827 if (is
->videoq
.abort_request
)
1831 /* if the frame is not skipped, then display it */
1833 AVPicture pict
= { { 0 } };
1835 /* get a pointer on the bitmap */
1836 SDL_LockYUVOverlay (vp
->bmp
);
1838 pict
.data
[0] = vp
->bmp
->pixels
[0];
1839 pict
.data
[1] = vp
->bmp
->pixels
[2];
1840 pict
.data
[2] = vp
->bmp
->pixels
[1];
1842 pict
.linesize
[0] = vp
->bmp
->pitches
[0];
1843 pict
.linesize
[1] = vp
->bmp
->pitches
[2];
1844 pict
.linesize
[2] = vp
->bmp
->pitches
[1];
1847 // FIXME use direct rendering
1848 av_picture_copy(&pict
, (AVPicture
*)src_frame
,
1849 src_frame
->format
, vp
->width
, vp
->height
);
1851 av_opt_get_int(sws_opts
, "sws_flags", 0, &sws_flags
);
1852 is
->img_convert_ctx
= sws_getCachedContext(is
->img_convert_ctx
,
1853 vp
->width
, vp
->height
, src_frame
->format
, vp
->width
, vp
->height
,
1854 AV_PIX_FMT_YUV420P
, sws_flags
, NULL
, NULL
, NULL
);
1855 if (!is
->img_convert_ctx
) {
1856 av_log(NULL
, AV_LOG_FATAL
, "Cannot initialize the conversion context\n");
1859 sws_scale(is
->img_convert_ctx
, src_frame
->data
, src_frame
->linesize
,
1860 0, vp
->height
, pict
.data
, pict
.linesize
);
1862 /* workaround SDL PITCH_WORKAROUND */
1863 duplicate_right_border_pixels(vp
->bmp
);
1864 /* update the bitmap content */
1865 SDL_UnlockYUVOverlay(vp
->bmp
);
1868 vp
->duration
= duration
;
1870 vp
->serial
= serial
;
1872 /* now we can update the picture count */
1873 frame_queue_push(&is
->pictq
);
1878 static int get_video_frame(VideoState
*is
, AVFrame
*frame
)
1882 if ((got_picture
= decoder_decode_frame(&is
->viddec
, frame
, NULL
)) < 0)
1888 if (frame
->pts
!= AV_NOPTS_VALUE
)
1889 dpts
= av_q2d(is
->video_st
->time_base
) * frame
->pts
;
1891 frame
->sample_aspect_ratio
= av_guess_sample_aspect_ratio(is
->ic
, is
->video_st
, frame
);
1893 if (framedrop
>0 || (framedrop
&& get_master_sync_type(is
) != AV_SYNC_VIDEO_MASTER
)) {
1894 if (frame
->pts
!= AV_NOPTS_VALUE
) {
1895 double diff
= dpts
- get_master_clock(is
);
1896 if (!isnan(diff
) && fabs(diff
) < AV_NOSYNC_THRESHOLD
&&
1897 diff
- is
->frame_last_filter_delay
< 0 &&
1898 is
->viddec
.pkt_serial
== is
->vidclk
.serial
&&
1899 is
->videoq
.nb_packets
) {
1900 is
->frame_drops_early
++;
1901 av_frame_unref(frame
);
1912 static int configure_filtergraph(AVFilterGraph
*graph
, const char *filtergraph
,
1913 AVFilterContext
*source_ctx
, AVFilterContext
*sink_ctx
)
1916 int nb_filters
= graph
->nb_filters
;
1917 AVFilterInOut
*outputs
= NULL
, *inputs
= NULL
;
1920 outputs
= avfilter_inout_alloc();
1921 inputs
= avfilter_inout_alloc();
1922 if (!outputs
|| !inputs
) {
1923 ret
= AVERROR(ENOMEM
);
1927 outputs
->name
= av_strdup("in");
1928 outputs
->filter_ctx
= source_ctx
;
1929 outputs
->pad_idx
= 0;
1930 outputs
->next
= NULL
;
1932 inputs
->name
= av_strdup("out");
1933 inputs
->filter_ctx
= sink_ctx
;
1934 inputs
->pad_idx
= 0;
1935 inputs
->next
= NULL
;
1937 if ((ret
= avfilter_graph_parse_ptr(graph
, filtergraph
, &inputs
, &outputs
, NULL
)) < 0)
1940 if ((ret
= avfilter_link(source_ctx
, 0, sink_ctx
, 0)) < 0)
1944 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1945 for (i
= 0; i
< graph
->nb_filters
- nb_filters
; i
++)
1946 FFSWAP(AVFilterContext
*, graph
->filters
[i
], graph
->filters
[i
+ nb_filters
]);
1948 ret
= avfilter_graph_config(graph
, NULL
);
1950 avfilter_inout_free(&outputs
);
1951 avfilter_inout_free(&inputs
);
1955 static int configure_video_filters(AVFilterGraph
*graph
, VideoState
*is
, const char *vfilters
, AVFrame
*frame
)
1957 static const enum AVPixelFormat pix_fmts
[] = { AV_PIX_FMT_YUV420P
, AV_PIX_FMT_NONE
};
1958 char sws_flags_str
[128];
1959 char buffersrc_args
[256];
1961 AVFilterContext
*filt_src
= NULL
, *filt_out
= NULL
, *last_filter
= NULL
;
1962 AVCodecContext
*codec
= is
->video_st
->codec
;
1963 AVRational fr
= av_guess_frame_rate(is
->ic
, is
->video_st
, NULL
);
1965 av_opt_get_int(sws_opts
, "sws_flags", 0, &sws_flags
);
1966 snprintf(sws_flags_str
, sizeof(sws_flags_str
), "flags=%"PRId64
, sws_flags
);
1967 graph
->scale_sws_opts
= av_strdup(sws_flags_str
);
1969 snprintf(buffersrc_args
, sizeof(buffersrc_args
),
1970 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1971 frame
->width
, frame
->height
, frame
->format
,
1972 is
->video_st
->time_base
.num
, is
->video_st
->time_base
.den
,
1973 codec
->sample_aspect_ratio
.num
, FFMAX(codec
->sample_aspect_ratio
.den
, 1));
1974 if (fr
.num
&& fr
.den
)
1975 av_strlcatf(buffersrc_args
, sizeof(buffersrc_args
), ":frame_rate=%d/%d", fr
.num
, fr
.den
);
1977 if ((ret
= avfilter_graph_create_filter(&filt_src
,
1978 avfilter_get_by_name("buffer"),
1979 "ffplay_buffer", buffersrc_args
, NULL
,
1983 ret
= avfilter_graph_create_filter(&filt_out
,
1984 avfilter_get_by_name("buffersink"),
1985 "ffplay_buffersink", NULL
, NULL
, graph
);
1989 if ((ret
= av_opt_set_int_list(filt_out
, "pix_fmts", pix_fmts
, AV_PIX_FMT_NONE
, AV_OPT_SEARCH_CHILDREN
)) < 0)
1992 last_filter
= filt_out
;
1994 /* Note: this macro adds a filter before the lastly added filter, so the
1995 * processing order of the filters is in reverse */
1996 #define INSERT_FILT(name, arg) do { \
1997 AVFilterContext *filt_ctx; \
1999 ret = avfilter_graph_create_filter(&filt_ctx, \
2000 avfilter_get_by_name(name), \
2001 "ffplay_" name, arg, NULL, graph); \
2005 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
2009 last_filter = filt_ctx; \
2012 /* SDL YUV code is not handling odd width/height for some driver
2013 * combinations, therefore we crop the picture to an even width/height. */
2014 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
2017 AVDictionaryEntry
*rotate_tag
= av_dict_get(is
->video_st
->metadata
, "rotate", NULL
, 0);
2018 if (rotate_tag
&& *rotate_tag
->value
&& strcmp(rotate_tag
->value
, "0")) {
2019 if (!strcmp(rotate_tag
->value
, "90")) {
2020 INSERT_FILT("transpose", "clock");
2021 } else if (!strcmp(rotate_tag
->value
, "180")) {
2022 INSERT_FILT("hflip", NULL
);
2023 INSERT_FILT("vflip", NULL
);
2024 } else if (!strcmp(rotate_tag
->value
, "270")) {
2025 INSERT_FILT("transpose", "cclock");
2027 char rotate_buf
[64];
2028 snprintf(rotate_buf
, sizeof(rotate_buf
), "%s*PI/180", rotate_tag
->value
);
2029 INSERT_FILT("rotate", rotate_buf
);
2034 if ((ret
= configure_filtergraph(graph
, vfilters
, filt_src
, last_filter
)) < 0)
2037 is
->in_video_filter
= filt_src
;
2038 is
->out_video_filter
= filt_out
;
2044 static int configure_audio_filters(VideoState
*is
, const char *afilters
, int force_output_format
)
2046 static const enum AVSampleFormat sample_fmts
[] = { AV_SAMPLE_FMT_S16
, AV_SAMPLE_FMT_NONE
};
2047 int sample_rates
[2] = { 0, -1 };
2048 int64_t channel_layouts
[2] = { 0, -1 };
2049 int channels
[2] = { 0, -1 };
2050 AVFilterContext
*filt_asrc
= NULL
, *filt_asink
= NULL
;
2051 char aresample_swr_opts
[512] = "";
2052 AVDictionaryEntry
*e
= NULL
;
2053 char asrc_args
[256];
2056 avfilter_graph_free(&is
->agraph
);
2057 if (!(is
->agraph
= avfilter_graph_alloc()))
2058 return AVERROR(ENOMEM
);
2060 while ((e
= av_dict_get(swr_opts
, "", e
, AV_DICT_IGNORE_SUFFIX
)))
2061 av_strlcatf(aresample_swr_opts
, sizeof(aresample_swr_opts
), "%s=%s:", e
->key
, e
->value
);
2062 if (strlen(aresample_swr_opts
))
2063 aresample_swr_opts
[strlen(aresample_swr_opts
)-1] = '\0';
2064 av_opt_set(is
->agraph
, "aresample_swr_opts", aresample_swr_opts
, 0);
2066 ret
= snprintf(asrc_args
, sizeof(asrc_args
),
2067 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
2068 is
->audio_filter_src
.freq
, av_get_sample_fmt_name(is
->audio_filter_src
.fmt
),
2069 is
->audio_filter_src
.channels
,
2070 1, is
->audio_filter_src
.freq
);
2071 if (is
->audio_filter_src
.channel_layout
)
2072 snprintf(asrc_args
+ ret
, sizeof(asrc_args
) - ret
,
2073 ":channel_layout=0x%"PRIx64
, is
->audio_filter_src
.channel_layout
);
2075 ret
= avfilter_graph_create_filter(&filt_asrc
,
2076 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
2077 asrc_args
, NULL
, is
->agraph
);
2082 ret
= avfilter_graph_create_filter(&filt_asink
,
2083 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
2084 NULL
, NULL
, is
->agraph
);
2088 if ((ret
= av_opt_set_int_list(filt_asink
, "sample_fmts", sample_fmts
, AV_SAMPLE_FMT_NONE
, AV_OPT_SEARCH_CHILDREN
)) < 0)
2090 if ((ret
= av_opt_set_int(filt_asink
, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN
)) < 0)
2093 if (force_output_format
) {
2094 channel_layouts
[0] = is
->audio_tgt
.channel_layout
;
2095 channels
[0] = is
->audio_tgt
.channels
;
2096 sample_rates
[0] = is
->audio_tgt
.freq
;
2097 if ((ret
= av_opt_set_int(filt_asink
, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN
)) < 0)
2099 if ((ret
= av_opt_set_int_list(filt_asink
, "channel_layouts", channel_layouts
, -1, AV_OPT_SEARCH_CHILDREN
)) < 0)
2101 if ((ret
= av_opt_set_int_list(filt_asink
, "channel_counts" , channels
, -1, AV_OPT_SEARCH_CHILDREN
)) < 0)
2103 if ((ret
= av_opt_set_int_list(filt_asink
, "sample_rates" , sample_rates
, -1, AV_OPT_SEARCH_CHILDREN
)) < 0)
2108 if ((ret
= configure_filtergraph(is
->agraph
, afilters
, filt_asrc
, filt_asink
)) < 0)
2111 is
->in_audio_filter
= filt_asrc
;
2112 is
->out_audio_filter
= filt_asink
;
2116 avfilter_graph_free(&is
->agraph
);
2119 #endif /* CONFIG_AVFILTER */
2121 static int audio_thread(void *arg
)
2123 VideoState
*is
= arg
;
2124 AVFrame
*frame
= av_frame_alloc();
2127 int last_serial
= -1;
2128 int64_t dec_channel_layout
;
2136 return AVERROR(ENOMEM
);
2139 if ((got_frame
= decoder_decode_frame(&is
->auddec
, frame
, NULL
)) < 0)
2143 tb
= (AVRational
){1, frame
->sample_rate
};
2146 dec_channel_layout
= get_valid_channel_layout(frame
->channel_layout
, av_frame_get_channels(frame
));
2149 cmp_audio_fmts(is
->audio_filter_src
.fmt
, is
->audio_filter_src
.channels
,
2150 frame
->format
, av_frame_get_channels(frame
)) ||
2151 is
->audio_filter_src
.channel_layout
!= dec_channel_layout
||
2152 is
->audio_filter_src
.freq
!= frame
->sample_rate
||
2153 is
->auddec
.pkt_serial
!= last_serial
;
2156 char buf1
[1024], buf2
[1024];
2157 av_get_channel_layout_string(buf1
, sizeof(buf1
), -1, is
->audio_filter_src
.channel_layout
);
2158 av_get_channel_layout_string(buf2
, sizeof(buf2
), -1, dec_channel_layout
);
2159 av_log(NULL
, AV_LOG_DEBUG
,
2160 "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",
2161 is
->audio_filter_src
.freq
, is
->audio_filter_src
.channels
, av_get_sample_fmt_name(is
->audio_filter_src
.fmt
), buf1
, last_serial
,
2162 frame
->sample_rate
, av_frame_get_channels(frame
), av_get_sample_fmt_name(frame
->format
), buf2
, is
->auddec
.pkt_serial
);
2164 is
->audio_filter_src
.fmt
= frame
->format
;
2165 is
->audio_filter_src
.channels
= av_frame_get_channels(frame
);
2166 is
->audio_filter_src
.channel_layout
= dec_channel_layout
;
2167 is
->audio_filter_src
.freq
= frame
->sample_rate
;
2168 last_serial
= is
->auddec
.pkt_serial
;
2170 if ((ret
= configure_audio_filters(is
, afilters
, 1)) < 0)
2174 if ((ret
= av_buffersrc_add_frame(is
->in_audio_filter
, frame
)) < 0)
2177 while ((ret
= av_buffersink_get_frame_flags(is
->out_audio_filter
, frame
, 0)) >= 0) {
2178 tb
= is
->out_audio_filter
->inputs
[0]->time_base
;
2180 if (!(af
= frame_queue_peek_writable(&is
->sampq
)))
2183 af
->pts
= (frame
->pts
== AV_NOPTS_VALUE
) ? NAN
: frame
->pts
* av_q2d(tb
);
2184 af
->pos
= av_frame_get_pkt_pos(frame
);
2185 af
->serial
= is
->auddec
.pkt_serial
;
2186 af
->duration
= av_q2d((AVRational
){frame
->nb_samples
, frame
->sample_rate
});
2188 av_frame_move_ref(af
->frame
, frame
);
2189 frame_queue_push(&is
->sampq
);
2192 if (is
->audioq
.serial
!= is
->auddec
.pkt_serial
)
2195 if (ret
== AVERROR_EOF
)
2196 is
->auddec
.finished
= is
->auddec
.pkt_serial
;
2199 } while (ret
>= 0 || ret
== AVERROR(EAGAIN
) || ret
== AVERROR_EOF
);
2202 avfilter_graph_free(&is
->agraph
);
2204 av_frame_free(&frame
);
2208 static int video_thread(void *arg
)
2210 VideoState
*is
= arg
;
2211 AVFrame
*frame
= av_frame_alloc();
2215 AVRational tb
= is
->video_st
->time_base
;
2216 AVRational frame_rate
= av_guess_frame_rate(is
->ic
, is
->video_st
, NULL
);
2219 AVFilterGraph
*graph
= avfilter_graph_alloc();
2220 AVFilterContext
*filt_out
= NULL
, *filt_in
= NULL
;
2223 enum AVPixelFormat last_format
= -2;
2224 int last_serial
= -1;
2225 int last_vfilter_idx
= 0;
2229 ret
= get_video_frame(is
, frame
);
2236 if ( last_w
!= frame
->width
2237 || last_h
!= frame
->height
2238 || last_format
!= frame
->format
2239 || last_serial
!= is
->viddec
.pkt_serial
2240 || last_vfilter_idx
!= is
->vfilter_idx
) {
2241 av_log(NULL
, AV_LOG_DEBUG
,
2242 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2244 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format
), "none"), last_serial
,
2245 frame
->width
, frame
->height
,
2246 (const char *)av_x_if_null(av_get_pix_fmt_name(frame
->format
), "none"), is
->viddec
.pkt_serial
);
2247 avfilter_graph_free(&graph
);
2248 graph
= avfilter_graph_alloc();
2249 if ((ret
= configure_video_filters(graph
, is
, vfilters_list
? vfilters_list
[is
->vfilter_idx
] : NULL
, frame
)) < 0) {
2251 event
.type
= FF_QUIT_EVENT
;
2252 event
.user
.data1
= is
;
2253 SDL_PushEvent(&event
);
2256 filt_in
= is
->in_video_filter
;
2257 filt_out
= is
->out_video_filter
;
2258 last_w
= frame
->width
;
2259 last_h
= frame
->height
;
2260 last_format
= frame
->format
;
2261 last_serial
= is
->viddec
.pkt_serial
;
2262 last_vfilter_idx
= is
->vfilter_idx
;
2263 frame_rate
= filt_out
->inputs
[0]->frame_rate
;
2266 ret
= av_buffersrc_add_frame(filt_in
, frame
);
2271 is
->frame_last_returned_time
= av_gettime_relative() / 1000000.0;
2273 ret
= av_buffersink_get_frame_flags(filt_out
, frame
, 0);
2275 if (ret
== AVERROR_EOF
)
2276 is
->viddec
.finished
= is
->viddec
.pkt_serial
;
2281 is
->frame_last_filter_delay
= av_gettime_relative() / 1000000.0 - is
->frame_last_returned_time
;
2282 if (fabs(is
->frame_last_filter_delay
) > AV_NOSYNC_THRESHOLD
/ 10.0)
2283 is
->frame_last_filter_delay
= 0;
2284 tb
= filt_out
->inputs
[0]->time_base
;
2286 duration
= (frame_rate
.num
&& frame_rate
.den
? av_q2d((AVRational
){frame_rate
.den
, frame_rate
.num
}) : 0);
2287 pts
= (frame
->pts
== AV_NOPTS_VALUE
) ? NAN
: frame
->pts
* av_q2d(tb
);
2288 ret
= queue_picture(is
, frame
, pts
, duration
, av_frame_get_pkt_pos(frame
), is
->viddec
.pkt_serial
);
2289 av_frame_unref(frame
);
2299 avfilter_graph_free(&graph
);
2301 av_frame_free(&frame
);
2305 static int subtitle_thread(void *arg
)
2307 VideoState
*is
= arg
;
2312 int r
, g
, b
, y
, u
, v
, a
;
2315 if (!(sp
= frame_queue_peek_writable(&is
->subpq
)))
2318 if ((got_subtitle
= decoder_decode_frame(&is
->subdec
, NULL
, &sp
->sub
)) < 0)
2323 if (got_subtitle
&& sp
->sub
.format
== 0) {
2324 if (sp
->sub
.pts
!= AV_NOPTS_VALUE
)
2325 pts
= sp
->sub
.pts
/ (double)AV_TIME_BASE
;
2327 sp
->serial
= is
->subdec
.pkt_serial
;
2329 for (i
= 0; i
< sp
->sub
.num_rects
; i
++)
2331 for (j
= 0; j
< sp
->sub
.rects
[i
]->nb_colors
; j
++)
2333 RGBA_IN(r
, g
, b
, a
, (uint32_t*)sp
->sub
.rects
[i
]->pict
.data
[1] + j
);
2334 y
= RGB_TO_Y_CCIR(r
, g
, b
);
2335 u
= RGB_TO_U_CCIR(r
, g
, b
, 0);
2336 v
= RGB_TO_V_CCIR(r
, g
, b
, 0);
2337 YUVA_OUT((uint32_t*)sp
->sub
.rects
[i
]->pict
.data
[1] + j
, y
, u
, v
, a
);
2341 /* now we can update the picture count */
2342 frame_queue_push(&is
->subpq
);
2343 } else if (got_subtitle
) {
2344 avsubtitle_free(&sp
->sub
);
2350 /* copy samples for viewing in editor window */
2351 static void update_sample_display(VideoState
*is
, short *samples
, int samples_size
)
2355 size
= samples_size
/ sizeof(short);
2357 len
= SAMPLE_ARRAY_SIZE
- is
->sample_array_index
;
2360 memcpy(is
->sample_array
+ is
->sample_array_index
, samples
, len
* sizeof(short));
2362 is
->sample_array_index
+= len
;
2363 if (is
->sample_array_index
>= SAMPLE_ARRAY_SIZE
)
2364 is
->sample_array_index
= 0;
2369 /* return the wanted number of samples to get better sync if sync_type is video
2370 * or external master clock */
2371 static int synchronize_audio(VideoState
*is
, int nb_samples
)
2373 int wanted_nb_samples
= nb_samples
;
2375 /* if not master, then we try to remove or add samples to correct the clock */
2376 if (get_master_sync_type(is
) != AV_SYNC_AUDIO_MASTER
) {
2377 double diff
, avg_diff
;
2378 int min_nb_samples
, max_nb_samples
;
2380 diff
= get_clock(&is
->audclk
) - get_master_clock(is
);
2382 if (!isnan(diff
) && fabs(diff
) < AV_NOSYNC_THRESHOLD
) {
2383 is
->audio_diff_cum
= diff
+ is
->audio_diff_avg_coef
* is
->audio_diff_cum
;
2384 if (is
->audio_diff_avg_count
< AUDIO_DIFF_AVG_NB
) {
2385 /* not enough measures to have a correct estimate */
2386 is
->audio_diff_avg_count
++;
2388 /* estimate the A-V difference */
2389 avg_diff
= is
->audio_diff_cum
* (1.0 - is
->audio_diff_avg_coef
);
2391 if (fabs(avg_diff
) >= is
->audio_diff_threshold
) {
2392 wanted_nb_samples
= nb_samples
+ (int)(diff
* is
->audio_src
.freq
);
2393 min_nb_samples
= ((nb_samples
* (100 - SAMPLE_CORRECTION_PERCENT_MAX
) / 100));
2394 max_nb_samples
= ((nb_samples
* (100 + SAMPLE_CORRECTION_PERCENT_MAX
) / 100));
2395 wanted_nb_samples
= FFMIN(FFMAX(wanted_nb_samples
, min_nb_samples
), max_nb_samples
);
2397 av_dlog(NULL
, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2398 diff
, avg_diff
, wanted_nb_samples
- nb_samples
,
2399 is
->audio_clock
, is
->audio_diff_threshold
);
2402 /* too big difference : may be initial PTS errors, so
2404 is
->audio_diff_avg_count
= 0;
2405 is
->audio_diff_cum
= 0;
2409 return wanted_nb_samples
;
2413 * Decode one audio frame and return its uncompressed size.
2415 * The processed audio frame is decoded, converted if required, and
2416 * stored in is->audio_buf, with size in bytes given by the return
2419 static int audio_decode_frame(VideoState
*is
)
2421 int data_size
, resampled_data_size
;
2422 int64_t dec_channel_layout
;
2423 av_unused
double audio_clock0
;
2424 int wanted_nb_samples
;
2431 if (!(af
= frame_queue_peek_readable(&is
->sampq
)))
2433 frame_queue_next(&is
->sampq
);
2434 } while (af
->serial
!= is
->audioq
.serial
);
2436 data_size
= av_samples_get_buffer_size(NULL
, av_frame_get_channels(af
->frame
),
2437 af
->frame
->nb_samples
,
2438 af
->frame
->format
, 1);
2440 dec_channel_layout
=
2441 (af
->frame
->channel_layout
&& av_frame_get_channels(af
->frame
) == av_get_channel_layout_nb_channels(af
->frame
->channel_layout
)) ?
2442 af
->frame
->channel_layout
: av_get_default_channel_layout(av_frame_get_channels(af
->frame
));
2443 wanted_nb_samples
= synchronize_audio(is
, af
->frame
->nb_samples
);
2445 if (af
->frame
->format
!= is
->audio_src
.fmt
||
2446 dec_channel_layout
!= is
->audio_src
.channel_layout
||
2447 af
->frame
->sample_rate
!= is
->audio_src
.freq
||
2448 (wanted_nb_samples
!= af
->frame
->nb_samples
&& !is
->swr_ctx
)) {
2449 swr_free(&is
->swr_ctx
);
2450 is
->swr_ctx
= swr_alloc_set_opts(NULL
,
2451 is
->audio_tgt
.channel_layout
, is
->audio_tgt
.fmt
, is
->audio_tgt
.freq
,
2452 dec_channel_layout
, af
->frame
->format
, af
->frame
->sample_rate
,
2454 if (!is
->swr_ctx
|| swr_init(is
->swr_ctx
) < 0) {
2455 av_log(NULL
, AV_LOG_ERROR
,
2456 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2457 af
->frame
->sample_rate
, av_get_sample_fmt_name(af
->frame
->format
), av_frame_get_channels(af
->frame
),
2458 is
->audio_tgt
.freq
, av_get_sample_fmt_name(is
->audio_tgt
.fmt
), is
->audio_tgt
.channels
);
2459 swr_free(&is
->swr_ctx
);
2462 is
->audio_src
.channel_layout
= dec_channel_layout
;
2463 is
->audio_src
.channels
= av_frame_get_channels(af
->frame
);
2464 is
->audio_src
.freq
= af
->frame
->sample_rate
;
2465 is
->audio_src
.fmt
= af
->frame
->format
;
2469 const uint8_t **in
= (const uint8_t **)af
->frame
->extended_data
;
2470 uint8_t **out
= &is
->audio_buf1
;
2471 int out_count
= (int64_t)wanted_nb_samples
* is
->audio_tgt
.freq
/ af
->frame
->sample_rate
+ 256;
2472 int out_size
= av_samples_get_buffer_size(NULL
, is
->audio_tgt
.channels
, out_count
, is
->audio_tgt
.fmt
, 0);
2475 av_log(NULL
, AV_LOG_ERROR
, "av_samples_get_buffer_size() failed\n");
2478 if (wanted_nb_samples
!= af
->frame
->nb_samples
) {
2479 if (swr_set_compensation(is
->swr_ctx
, (wanted_nb_samples
- af
->frame
->nb_samples
) * is
->audio_tgt
.freq
/ af
->frame
->sample_rate
,
2480 wanted_nb_samples
* is
->audio_tgt
.freq
/ af
->frame
->sample_rate
) < 0) {
2481 av_log(NULL
, AV_LOG_ERROR
, "swr_set_compensation() failed\n");
2485 av_fast_malloc(&is
->audio_buf1
, &is
->audio_buf1_size
, out_size
);
2486 if (!is
->audio_buf1
)
2487 return AVERROR(ENOMEM
);
2488 len2
= swr_convert(is
->swr_ctx
, out
, out_count
, in
, af
->frame
->nb_samples
);
2490 av_log(NULL
, AV_LOG_ERROR
, "swr_convert() failed\n");
2493 if (len2
== out_count
) {
2494 av_log(NULL
, AV_LOG_WARNING
, "audio buffer is probably too small\n");
2495 if (swr_init(is
->swr_ctx
) < 0)
2496 swr_free(&is
->swr_ctx
);
2498 is
->audio_buf
= is
->audio_buf1
;
2499 resampled_data_size
= len2
* is
->audio_tgt
.channels
* av_get_bytes_per_sample(is
->audio_tgt
.fmt
);
2501 is
->audio_buf
= af
->frame
->data
[0];
2502 resampled_data_size
= data_size
;
2505 audio_clock0
= is
->audio_clock
;
2506 /* update the audio clock with the pts */
2507 if (!isnan(af
->pts
))
2508 is
->audio_clock
= af
->pts
+ (double) af
->frame
->nb_samples
/ af
->frame
->sample_rate
;
2510 is
->audio_clock
= NAN
;
2511 is
->audio_clock_serial
= af
->serial
;
2514 static double last_clock
;
2515 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2516 is
->audio_clock
- last_clock
,
2517 is
->audio_clock
, audio_clock0
);
2518 last_clock
= is
->audio_clock
;
2521 return resampled_data_size
;
2524 /* prepare a new audio buffer */
2525 static void sdl_audio_callback(void *opaque
, Uint8
*stream
, int len
)
2527 VideoState
*is
= opaque
;
2528 int audio_size
, len1
;
2530 audio_callback_time
= av_gettime_relative();
2533 if (is
->audio_buf_index
>= is
->audio_buf_size
) {
2534 audio_size
= audio_decode_frame(is
);
2535 if (audio_size
< 0) {
2536 /* if error, just output silence */
2537 is
->audio_buf
= is
->silence_buf
;
2538 is
->audio_buf_size
= sizeof(is
->silence_buf
) / is
->audio_tgt
.frame_size
* is
->audio_tgt
.frame_size
;
2540 if (is
->show_mode
!= SHOW_MODE_VIDEO
)
2541 update_sample_display(is
, (int16_t *)is
->audio_buf
, audio_size
);
2542 is
->audio_buf_size
= audio_size
;
2544 is
->audio_buf_index
= 0;
2546 len1
= is
->audio_buf_size
- is
->audio_buf_index
;
2549 memcpy(stream
, (uint8_t *)is
->audio_buf
+ is
->audio_buf_index
, len1
);
2552 is
->audio_buf_index
+= len1
;
2554 is
->audio_write_buf_size
= is
->audio_buf_size
- is
->audio_buf_index
;
2555 /* Let's assume the audio driver that is used by SDL has two periods. */
2556 if (!isnan(is
->audio_clock
)) {
2557 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);
2558 sync_clock_to_slave(&is
->extclk
, &is
->audclk
);
2562 static int audio_open(void *opaque
, int64_t wanted_channel_layout
, int wanted_nb_channels
, int wanted_sample_rate
, struct AudioParams
*audio_hw_params
)
2564 SDL_AudioSpec wanted_spec
, spec
;
2566 static const int next_nb_channels
[] = {0, 0, 1, 6, 2, 6, 4, 6};
2567 static const int next_sample_rates
[] = {0, 44100, 48000, 96000, 192000};
2568 int next_sample_rate_idx
= FF_ARRAY_ELEMS(next_sample_rates
) - 1;
2570 env
= SDL_getenv("SDL_AUDIO_CHANNELS");
2572 wanted_nb_channels
= atoi(env
);
2573 wanted_channel_layout
= av_get_default_channel_layout(wanted_nb_channels
);
2575 if (!wanted_channel_layout
|| wanted_nb_channels
!= av_get_channel_layout_nb_channels(wanted_channel_layout
)) {
2576 wanted_channel_layout
= av_get_default_channel_layout(wanted_nb_channels
);
2577 wanted_channel_layout
&= ~AV_CH_LAYOUT_STEREO_DOWNMIX
;
2579 wanted_nb_channels
= av_get_channel_layout_nb_channels(wanted_channel_layout
);
2580 wanted_spec
.channels
= wanted_nb_channels
;
2581 wanted_spec
.freq
= wanted_sample_rate
;
2582 if (wanted_spec
.freq
<= 0 || wanted_spec
.channels
<= 0) {
2583 av_log(NULL
, AV_LOG_ERROR
, "Invalid sample rate or channel count!\n");
2586 while (next_sample_rate_idx
&& next_sample_rates
[next_sample_rate_idx
] >= wanted_spec
.freq
)
2587 next_sample_rate_idx
--;
2588 wanted_spec
.format
= AUDIO_S16SYS
;
2589 wanted_spec
.silence
= 0;
2590 wanted_spec
.samples
= FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE
, 2 << av_log2(wanted_spec
.freq
/ SDL_AUDIO_MAX_CALLBACKS_PER_SEC
));
2591 wanted_spec
.callback
= sdl_audio_callback
;
2592 wanted_spec
.userdata
= opaque
;
2593 while (SDL_OpenAudio(&wanted_spec
, &spec
) < 0) {
2594 av_log(NULL
, AV_LOG_WARNING
, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2595 wanted_spec
.channels
, wanted_spec
.freq
, SDL_GetError());
2596 wanted_spec
.channels
= next_nb_channels
[FFMIN(7, wanted_spec
.channels
)];
2597 if (!wanted_spec
.channels
) {
2598 wanted_spec
.freq
= next_sample_rates
[next_sample_rate_idx
--];
2599 wanted_spec
.channels
= wanted_nb_channels
;
2600 if (!wanted_spec
.freq
) {
2601 av_log(NULL
, AV_LOG_ERROR
,
2602 "No more combinations to try, audio open failed\n");
2606 wanted_channel_layout
= av_get_default_channel_layout(wanted_spec
.channels
);
2608 if (spec
.format
!= AUDIO_S16SYS
) {
2609 av_log(NULL
, AV_LOG_ERROR
,
2610 "SDL advised audio format %d is not supported!\n", spec
.format
);
2613 if (spec
.channels
!= wanted_spec
.channels
) {
2614 wanted_channel_layout
= av_get_default_channel_layout(spec
.channels
);
2615 if (!wanted_channel_layout
) {
2616 av_log(NULL
, AV_LOG_ERROR
,
2617 "SDL advised channel count %d is not supported!\n", spec
.channels
);
2622 audio_hw_params
->fmt
= AV_SAMPLE_FMT_S16
;
2623 audio_hw_params
->freq
= spec
.freq
;
2624 audio_hw_params
->channel_layout
= wanted_channel_layout
;
2625 audio_hw_params
->channels
= spec
.channels
;
2626 audio_hw_params
->frame_size
= av_samples_get_buffer_size(NULL
, audio_hw_params
->channels
, 1, audio_hw_params
->fmt
, 1);
2627 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);
2628 if (audio_hw_params
->bytes_per_sec
<= 0 || audio_hw_params
->frame_size
<= 0) {
2629 av_log(NULL
, AV_LOG_ERROR
, "av_samples_get_buffer_size failed\n");
2635 /* open a given stream. Return 0 if OK */
2636 static int stream_component_open(VideoState
*is
, int stream_index
)
2638 AVFormatContext
*ic
= is
->ic
;
2639 AVCodecContext
*avctx
;
2641 const char *forced_codec_name
= NULL
;
2643 AVDictionaryEntry
*t
= NULL
;
2644 int sample_rate
, nb_channels
;
2645 int64_t channel_layout
;
2647 int stream_lowres
= lowres
;
2649 if (stream_index
< 0 || stream_index
>= ic
->nb_streams
)
2651 avctx
= ic
->streams
[stream_index
]->codec
;
2653 codec
= avcodec_find_decoder(avctx
->codec_id
);
2655 switch(avctx
->codec_type
){
2656 case AVMEDIA_TYPE_AUDIO
: is
->last_audio_stream
= stream_index
; forced_codec_name
= audio_codec_name
; break;
2657 case AVMEDIA_TYPE_SUBTITLE
: is
->last_subtitle_stream
= stream_index
; forced_codec_name
= subtitle_codec_name
; break;
2658 case AVMEDIA_TYPE_VIDEO
: is
->last_video_stream
= stream_index
; forced_codec_name
= video_codec_name
; break;
2660 if (forced_codec_name
)
2661 codec
= avcodec_find_decoder_by_name(forced_codec_name
);
2663 if (forced_codec_name
) av_log(NULL
, AV_LOG_WARNING
,
2664 "No codec could be found with name '%s'\n", forced_codec_name
);
2665 else av_log(NULL
, AV_LOG_WARNING
,
2666 "No codec could be found with id %d\n", avctx
->codec_id
);
2670 avctx
->codec_id
= codec
->id
;
2671 if(stream_lowres
> av_codec_get_max_lowres(codec
)){
2672 av_log(avctx
, AV_LOG_WARNING
, "The maximum value for lowres supported by the decoder is %d\n",
2673 av_codec_get_max_lowres(codec
));
2674 stream_lowres
= av_codec_get_max_lowres(codec
);
2676 av_codec_set_lowres(avctx
, stream_lowres
);
2678 if(stream_lowres
) avctx
->flags
|= CODEC_FLAG_EMU_EDGE
;
2679 if (fast
) avctx
->flags2
|= CODEC_FLAG2_FAST
;
2680 if(codec
->capabilities
& CODEC_CAP_DR1
)
2681 avctx
->flags
|= CODEC_FLAG_EMU_EDGE
;
2683 opts
= filter_codec_opts(codec_opts
, avctx
->codec_id
, ic
, ic
->streams
[stream_index
], codec
);
2684 if (!av_dict_get(opts
, "threads", NULL
, 0))
2685 av_dict_set(&opts
, "threads", "auto", 0);
2687 av_dict_set_int(&opts
, "lowres", stream_lowres
, 0);
2688 if (avctx
->codec_type
== AVMEDIA_TYPE_VIDEO
|| avctx
->codec_type
== AVMEDIA_TYPE_AUDIO
)
2689 av_dict_set(&opts
, "refcounted_frames", "1", 0);
2690 if ((ret
= avcodec_open2(avctx
, codec
, &opts
)) < 0) {
2693 if ((t
= av_dict_get(opts
, "", NULL
, AV_DICT_IGNORE_SUFFIX
))) {
2694 av_log(NULL
, AV_LOG_ERROR
, "Option %s not found.\n", t
->key
);
2695 ret
= AVERROR_OPTION_NOT_FOUND
;
2699 ic
->streams
[stream_index
]->discard
= AVDISCARD_DEFAULT
;
2700 switch (avctx
->codec_type
) {
2701 case AVMEDIA_TYPE_AUDIO
:
2706 is
->audio_filter_src
.freq
= avctx
->sample_rate
;
2707 is
->audio_filter_src
.channels
= avctx
->channels
;
2708 is
->audio_filter_src
.channel_layout
= get_valid_channel_layout(avctx
->channel_layout
, avctx
->channels
);
2709 is
->audio_filter_src
.fmt
= avctx
->sample_fmt
;
2710 if ((ret
= configure_audio_filters(is
, afilters
, 0)) < 0)
2712 link
= is
->out_audio_filter
->inputs
[0];
2713 sample_rate
= link
->sample_rate
;
2714 nb_channels
= link
->channels
;
2715 channel_layout
= link
->channel_layout
;
2718 sample_rate
= avctx
->sample_rate
;
2719 nb_channels
= avctx
->channels
;
2720 channel_layout
= avctx
->channel_layout
;
2723 /* prepare audio output */
2724 if ((ret
= audio_open(is
, channel_layout
, nb_channels
, sample_rate
, &is
->audio_tgt
)) < 0)
2726 is
->audio_hw_buf_size
= ret
;
2727 is
->audio_src
= is
->audio_tgt
;
2728 is
->audio_buf_size
= 0;
2729 is
->audio_buf_index
= 0;
2731 /* init averaging filter */
2732 is
->audio_diff_avg_coef
= exp(log(0.01) / AUDIO_DIFF_AVG_NB
);
2733 is
->audio_diff_avg_count
= 0;
2734 /* since we do not have a precise anough audio fifo fullness,
2735 we correct audio sync only if larger than this threshold */
2736 is
->audio_diff_threshold
= (double)(is
->audio_hw_buf_size
) / is
->audio_tgt
.bytes_per_sec
;
2738 is
->audio_stream
= stream_index
;
2739 is
->audio_st
= ic
->streams
[stream_index
];
2741 packet_queue_start(&is
->audioq
);
2742 decoder_init(&is
->auddec
, avctx
, &is
->audioq
, is
->continue_read_thread
);
2743 if ((is
->ic
->iformat
->flags
& (AVFMT_NOBINSEARCH
| AVFMT_NOGENSEARCH
| AVFMT_NO_BYTE_SEEK
)) && !is
->ic
->iformat
->read_seek
) {
2744 is
->auddec
.start_pts
= is
->audio_st
->start_time
;
2745 is
->auddec
.start_pts_tb
= is
->audio_st
->time_base
;
2747 is
->audio_tid
= SDL_CreateThread(audio_thread
, is
);
2750 case AVMEDIA_TYPE_VIDEO
:
2751 is
->video_stream
= stream_index
;
2752 is
->video_st
= ic
->streams
[stream_index
];
2754 packet_queue_start(&is
->videoq
);
2755 decoder_init(&is
->viddec
, avctx
, &is
->videoq
, is
->continue_read_thread
);
2756 is
->video_tid
= SDL_CreateThread(video_thread
, is
);
2757 is
->queue_attachments_req
= 1;
2759 case AVMEDIA_TYPE_SUBTITLE
:
2760 is
->subtitle_stream
= stream_index
;
2761 is
->subtitle_st
= ic
->streams
[stream_index
];
2763 packet_queue_start(&is
->subtitleq
);
2764 decoder_init(&is
->subdec
, avctx
, &is
->subtitleq
, is
->continue_read_thread
);
2765 is
->subtitle_tid
= SDL_CreateThread(subtitle_thread
, is
);
2772 av_dict_free(&opts
);
2777 static void stream_component_close(VideoState
*is
, int stream_index
)
2779 AVFormatContext
*ic
= is
->ic
;
2780 AVCodecContext
*avctx
;
2782 if (stream_index
< 0 || stream_index
>= ic
->nb_streams
)
2784 avctx
= ic
->streams
[stream_index
]->codec
;
2786 switch (avctx
->codec_type
) {
2787 case AVMEDIA_TYPE_AUDIO
:
2788 packet_queue_abort(&is
->audioq
);
2789 frame_queue_signal(&is
->sampq
);
2791 SDL_WaitThread(is
->audio_tid
, NULL
);
2793 decoder_destroy(&is
->auddec
);
2794 packet_queue_flush(&is
->audioq
);
2795 swr_free(&is
->swr_ctx
);
2796 av_freep(&is
->audio_buf1
);
2797 is
->audio_buf1_size
= 0;
2798 is
->audio_buf
= NULL
;
2801 av_rdft_end(is
->rdft
);
2802 av_freep(&is
->rdft_data
);
2807 case AVMEDIA_TYPE_VIDEO
:
2808 packet_queue_abort(&is
->videoq
);
2810 /* note: we also signal this mutex to make sure we deblock the
2811 video thread in all cases */
2812 frame_queue_signal(&is
->pictq
);
2814 SDL_WaitThread(is
->video_tid
, NULL
);
2816 decoder_destroy(&is
->viddec
);
2817 packet_queue_flush(&is
->videoq
);
2819 case AVMEDIA_TYPE_SUBTITLE
:
2820 packet_queue_abort(&is
->subtitleq
);
2822 /* note: we also signal this mutex to make sure we deblock the
2823 video thread in all cases */
2824 frame_queue_signal(&is
->subpq
);
2826 SDL_WaitThread(is
->subtitle_tid
, NULL
);
2828 decoder_destroy(&is
->subdec
);
2829 packet_queue_flush(&is
->subtitleq
);
2835 ic
->streams
[stream_index
]->discard
= AVDISCARD_ALL
;
2836 avcodec_close(avctx
);
2837 switch (avctx
->codec_type
) {
2838 case AVMEDIA_TYPE_AUDIO
:
2839 is
->audio_st
= NULL
;
2840 is
->audio_stream
= -1;
2842 case AVMEDIA_TYPE_VIDEO
:
2843 is
->video_st
= NULL
;
2844 is
->video_stream
= -1;
2846 case AVMEDIA_TYPE_SUBTITLE
:
2847 is
->subtitle_st
= NULL
;
2848 is
->subtitle_stream
= -1;
2855 static int decode_interrupt_cb(void *ctx
)
2857 VideoState
*is
= ctx
;
2858 return is
->abort_request
;
2861 static int is_realtime(AVFormatContext
*s
)
2863 if( !strcmp(s
->iformat
->name
, "rtp")
2864 || !strcmp(s
->iformat
->name
, "rtsp")
2865 || !strcmp(s
->iformat
->name
, "sdp")
2869 if(s
->pb
&& ( !strncmp(s
->filename
, "rtp:", 4)
2870 || !strncmp(s
->filename
, "udp:", 4)
2877 /* this thread gets the stream from the disk or the network */
2878 static int read_thread(void *arg
)
2880 VideoState
*is
= arg
;
2881 AVFormatContext
*ic
= NULL
;
2883 int st_index
[AVMEDIA_TYPE_NB
];
2884 AVPacket pkt1
, *pkt
= &pkt1
;
2886 int64_t stream_start_time
;
2887 int pkt_in_play_range
= 0;
2888 AVDictionaryEntry
*t
;
2889 AVDictionary
**opts
;
2890 int orig_nb_streams
;
2891 SDL_mutex
*wait_mutex
= SDL_CreateMutex();
2892 int scan_all_pmts_set
= 0;
2894 memset(st_index
, -1, sizeof(st_index
));
2895 is
->last_video_stream
= is
->video_stream
= -1;
2896 is
->last_audio_stream
= is
->audio_stream
= -1;
2897 is
->last_subtitle_stream
= is
->subtitle_stream
= -1;
2899 ic
= avformat_alloc_context();
2900 ic
->interrupt_callback
.callback
= decode_interrupt_cb
;
2901 ic
->interrupt_callback
.opaque
= is
;
2902 if (!av_dict_get(format_opts
, "scan_all_pmts", NULL
, AV_DICT_MATCH_CASE
)) {
2903 av_dict_set(&format_opts
, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE
);
2904 scan_all_pmts_set
= 1;
2906 err
= avformat_open_input(&ic
, is
->filename
, is
->iformat
, &format_opts
);
2908 print_error(is
->filename
, err
);
2912 if (scan_all_pmts_set
)
2913 av_dict_set(&format_opts
, "scan_all_pmts", NULL
, AV_DICT_MATCH_CASE
);
2915 if ((t
= av_dict_get(format_opts
, "", NULL
, AV_DICT_IGNORE_SUFFIX
))) {
2916 av_log(NULL
, AV_LOG_ERROR
, "Option %s not found.\n", t
->key
);
2917 ret
= AVERROR_OPTION_NOT_FOUND
;
2923 ic
->flags
|= AVFMT_FLAG_GENPTS
;
2925 av_format_inject_global_side_data(ic
);
2927 opts
= setup_find_stream_info_opts(ic
, codec_opts
);
2928 orig_nb_streams
= ic
->nb_streams
;
2930 err
= avformat_find_stream_info(ic
, opts
);
2932 for (i
= 0; i
< orig_nb_streams
; i
++)
2933 av_dict_free(&opts
[i
]);
2937 av_log(NULL
, AV_LOG_WARNING
,
2938 "%s: could not find codec parameters\n", is
->filename
);
2944 ic
->pb
->eof_reached
= 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2946 if (seek_by_bytes
< 0)
2947 seek_by_bytes
= !!(ic
->iformat
->flags
& AVFMT_TS_DISCONT
) && strcmp("ogg", ic
->iformat
->name
);
2949 is
->max_frame_duration
= (ic
->iformat
->flags
& AVFMT_TS_DISCONT
) ? 10.0 : 3600.0;
2951 if (!window_title
&& (t
= av_dict_get(ic
->metadata
, "title", NULL
, 0)))
2952 window_title
= av_asprintf("%s - %s", t
->value
, input_filename
);
2954 /* if seeking requested, we execute it */
2955 if (start_time
!= AV_NOPTS_VALUE
) {
2958 timestamp
= start_time
;
2959 /* add the stream start time */
2960 if (ic
->start_time
!= AV_NOPTS_VALUE
)
2961 timestamp
+= ic
->start_time
;
2962 ret
= avformat_seek_file(ic
, -1, INT64_MIN
, timestamp
, INT64_MAX
, 0);
2964 av_log(NULL
, AV_LOG_WARNING
, "%s: could not seek to position %0.3f\n",
2965 is
->filename
, (double)timestamp
/ AV_TIME_BASE
);
2969 is
->realtime
= is_realtime(ic
);
2971 for (i
= 0; i
< ic
->nb_streams
; i
++)
2972 ic
->streams
[i
]->discard
= AVDISCARD_ALL
;
2974 st_index
[AVMEDIA_TYPE_VIDEO
] =
2975 av_find_best_stream(ic
, AVMEDIA_TYPE_VIDEO
,
2976 wanted_stream
[AVMEDIA_TYPE_VIDEO
], -1, NULL
, 0);
2978 st_index
[AVMEDIA_TYPE_AUDIO
] =
2979 av_find_best_stream(ic
, AVMEDIA_TYPE_AUDIO
,
2980 wanted_stream
[AVMEDIA_TYPE_AUDIO
],
2981 st_index
[AVMEDIA_TYPE_VIDEO
],
2983 if (!video_disable
&& !subtitle_disable
)
2984 st_index
[AVMEDIA_TYPE_SUBTITLE
] =
2985 av_find_best_stream(ic
, AVMEDIA_TYPE_SUBTITLE
,
2986 wanted_stream
[AVMEDIA_TYPE_SUBTITLE
],
2987 (st_index
[AVMEDIA_TYPE_AUDIO
] >= 0 ?
2988 st_index
[AVMEDIA_TYPE_AUDIO
] :
2989 st_index
[AVMEDIA_TYPE_VIDEO
]),
2992 av_dump_format(ic
, 0, is
->filename
, 0);
2995 is
->show_mode
= show_mode
;
2996 if (st_index
[AVMEDIA_TYPE_VIDEO
] >= 0) {
2997 AVStream
*st
= ic
->streams
[st_index
[AVMEDIA_TYPE_VIDEO
]];
2998 AVCodecContext
*avctx
= st
->codec
;
2999 AVRational sar
= av_guess_sample_aspect_ratio(ic
, st
, NULL
);
3001 set_default_window_size(avctx
->width
, avctx
->height
, sar
);
3004 /* open the streams */
3005 if (st_index
[AVMEDIA_TYPE_AUDIO
] >= 0) {
3006 stream_component_open(is
, st_index
[AVMEDIA_TYPE_AUDIO
]);
3010 if (st_index
[AVMEDIA_TYPE_VIDEO
] >= 0) {
3011 ret
= stream_component_open(is
, st_index
[AVMEDIA_TYPE_VIDEO
]);
3013 if (is
->show_mode
== SHOW_MODE_NONE
)
3014 is
->show_mode
= ret
>= 0 ? SHOW_MODE_VIDEO
: SHOW_MODE_RDFT
;
3016 if (st_index
[AVMEDIA_TYPE_SUBTITLE
] >= 0) {
3017 stream_component_open(is
, st_index
[AVMEDIA_TYPE_SUBTITLE
]);
3020 if (is
->video_stream
< 0 && is
->audio_stream
< 0) {
3021 av_log(NULL
, AV_LOG_FATAL
, "Failed to open file '%s' or configure filtergraph\n",
3027 if (infinite_buffer
< 0 && is
->realtime
)
3028 infinite_buffer
= 1;
3031 if (is
->abort_request
)
3033 if (is
->paused
!= is
->last_paused
) {
3034 is
->last_paused
= is
->paused
;
3036 is
->read_pause_return
= av_read_pause(ic
);
3040 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
3042 (!strcmp(ic
->iformat
->name
, "rtsp") ||
3043 (ic
->pb
&& !strncmp(input_filename
, "mmsh:", 5)))) {
3044 /* wait 10 ms to avoid trying to get another packet */
3051 int64_t seek_target
= is
->seek_pos
;
3052 int64_t seek_min
= is
->seek_rel
> 0 ? seek_target
- is
->seek_rel
+ 2: INT64_MIN
;
3053 int64_t seek_max
= is
->seek_rel
< 0 ? seek_target
- is
->seek_rel
- 2: INT64_MAX
;
3054 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3055 // of the seek_pos/seek_rel variables
3057 ret
= avformat_seek_file(is
->ic
, -1, seek_min
, seek_target
, seek_max
, is
->seek_flags
);
3059 av_log(NULL
, AV_LOG_ERROR
,
3060 "%s: error while seeking\n", is
->ic
->filename
);
3062 if (is
->audio_stream
>= 0) {
3063 packet_queue_flush(&is
->audioq
);
3064 packet_queue_put(&is
->audioq
, &flush_pkt
);
3066 if (is
->subtitle_stream
>= 0) {
3067 packet_queue_flush(&is
->subtitleq
);
3068 packet_queue_put(&is
->subtitleq
, &flush_pkt
);
3070 if (is
->video_stream
>= 0) {
3071 packet_queue_flush(&is
->videoq
);
3072 packet_queue_put(&is
->videoq
, &flush_pkt
);
3074 if (is
->seek_flags
& AVSEEK_FLAG_BYTE
) {
3075 set_clock(&is
->extclk
, NAN
, 0);
3077 set_clock(&is
->extclk
, seek_target
/ (double)AV_TIME_BASE
, 0);
3081 is
->queue_attachments_req
= 1;
3084 step_to_next_frame(is
);
3086 if (is
->queue_attachments_req
) {
3087 if (is
->video_st
&& is
->video_st
->disposition
& AV_DISPOSITION_ATTACHED_PIC
) {
3089 if ((ret
= av_copy_packet(©
, &is
->video_st
->attached_pic
)) < 0)
3091 packet_queue_put(&is
->videoq
, ©
);
3092 packet_queue_put_nullpacket(&is
->videoq
, is
->video_stream
);
3094 is
->queue_attachments_req
= 0;
3097 /* if the queue are full, no need to read more */
3098 if (infinite_buffer
<1 &&
3099 (is
->audioq
.size
+ is
->videoq
.size
+ is
->subtitleq
.size
> MAX_QUEUE_SIZE
3100 || ( (is
->audioq
.nb_packets
> MIN_FRAMES
|| is
->audio_stream
< 0 || is
->audioq
.abort_request
)
3101 && (is
->videoq
.nb_packets
> MIN_FRAMES
|| is
->video_stream
< 0 || is
->videoq
.abort_request
3102 || (is
->video_st
->disposition
& AV_DISPOSITION_ATTACHED_PIC
))
3103 && (is
->subtitleq
.nb_packets
> MIN_FRAMES
|| is
->subtitle_stream
< 0 || is
->subtitleq
.abort_request
)))) {
3105 SDL_LockMutex(wait_mutex
);
3106 SDL_CondWaitTimeout(is
->continue_read_thread
, wait_mutex
, 10);
3107 SDL_UnlockMutex(wait_mutex
);
3111 (!is
->audio_st
|| (is
->auddec
.finished
== is
->audioq
.serial
&& frame_queue_nb_remaining(&is
->sampq
) == 0)) &&
3112 (!is
->video_st
|| (is
->viddec
.finished
== is
->videoq
.serial
&& frame_queue_nb_remaining(&is
->pictq
) == 0))) {
3113 if (loop
!= 1 && (!loop
|| --loop
)) {
3114 stream_seek(is
, start_time
!= AV_NOPTS_VALUE
? start_time
: 0, 0, 0);
3115 } else if (autoexit
) {
3120 ret
= av_read_frame(ic
, pkt
);
3122 if ((ret
== AVERROR_EOF
|| avio_feof(ic
->pb
)) && !eof
) {
3123 if (is
->video_stream
>= 0)
3124 packet_queue_put_nullpacket(&is
->videoq
, is
->video_stream
);
3125 if (is
->audio_stream
>= 0)
3126 packet_queue_put_nullpacket(&is
->audioq
, is
->audio_stream
);
3127 if (is
->subtitle_stream
>= 0)
3128 packet_queue_put_nullpacket(&is
->subtitleq
, is
->subtitle_stream
);
3131 if (ic
->pb
&& ic
->pb
->error
)
3133 SDL_LockMutex(wait_mutex
);
3134 SDL_CondWaitTimeout(is
->continue_read_thread
, wait_mutex
, 10);
3135 SDL_UnlockMutex(wait_mutex
);
3140 /* check if packet is in play range specified by user, then queue, otherwise discard */
3141 stream_start_time
= ic
->streams
[pkt
->stream_index
]->start_time
;
3142 pkt_in_play_range
= duration
== AV_NOPTS_VALUE
||
3143 (pkt
->pts
- (stream_start_time
!= AV_NOPTS_VALUE
? stream_start_time
: 0)) *
3144 av_q2d(ic
->streams
[pkt
->stream_index
]->time_base
) -
3145 (double)(start_time
!= AV_NOPTS_VALUE
? start_time
: 0) / 1000000
3146 <= ((double)duration
/ 1000000);
3147 if (pkt
->stream_index
== is
->audio_stream
&& pkt_in_play_range
) {
3148 packet_queue_put(&is
->audioq
, pkt
);
3149 } else if (pkt
->stream_index
== is
->video_stream
&& pkt_in_play_range
3150 && !(is
->video_st
->disposition
& AV_DISPOSITION_ATTACHED_PIC
)) {
3151 packet_queue_put(&is
->videoq
, pkt
);
3152 } else if (pkt
->stream_index
== is
->subtitle_stream
&& pkt_in_play_range
) {
3153 packet_queue_put(&is
->subtitleq
, pkt
);
3155 av_free_packet(pkt
);
3158 /* wait until the end */
3159 while (!is
->abort_request
) {
3165 /* close each stream */
3166 if (is
->audio_stream
>= 0)
3167 stream_component_close(is
, is
->audio_stream
);
3168 if (is
->video_stream
>= 0)
3169 stream_component_close(is
, is
->video_stream
);
3170 if (is
->subtitle_stream
>= 0)
3171 stream_component_close(is
, is
->subtitle_stream
);
3173 avformat_close_input(&ic
);
3180 event
.type
= FF_QUIT_EVENT
;
3181 event
.user
.data1
= is
;
3182 SDL_PushEvent(&event
);
3184 SDL_DestroyMutex(wait_mutex
);
3188 static VideoState
*stream_open(const char *filename
, AVInputFormat
*iformat
)
3192 is
= av_mallocz(sizeof(VideoState
));
3195 av_strlcpy(is
->filename
, filename
, sizeof(is
->filename
));
3196 is
->iformat
= iformat
;
3200 /* start video display */
3201 if (frame_queue_init(&is
->pictq
, &is
->videoq
, VIDEO_PICTURE_QUEUE_SIZE
, 1) < 0)
3203 if (frame_queue_init(&is
->subpq
, &is
->subtitleq
, SUBPICTURE_QUEUE_SIZE
, 0) < 0)
3205 if (frame_queue_init(&is
->sampq
, &is
->audioq
, SAMPLE_QUEUE_SIZE
, 1) < 0)
3208 packet_queue_init(&is
->videoq
);
3209 packet_queue_init(&is
->audioq
);
3210 packet_queue_init(&is
->subtitleq
);
3212 is
->continue_read_thread
= SDL_CreateCond();
3214 init_clock(&is
->vidclk
, &is
->videoq
.serial
);
3215 init_clock(&is
->audclk
, &is
->audioq
.serial
);
3216 init_clock(&is
->extclk
, &is
->extclk
.serial
);
3217 is
->audio_clock_serial
= -1;
3218 is
->av_sync_type
= av_sync_type
;
3219 is
->read_tid
= SDL_CreateThread(read_thread
, is
);
3220 if (!is
->read_tid
) {
3228 static void stream_cycle_channel(VideoState
*is
, int codec_type
)
3230 AVFormatContext
*ic
= is
->ic
;
3231 int start_index
, stream_index
;
3234 AVProgram
*p
= NULL
;
3235 int nb_streams
= is
->ic
->nb_streams
;
3237 if (codec_type
== AVMEDIA_TYPE_VIDEO
) {
3238 start_index
= is
->last_video_stream
;
3239 old_index
= is
->video_stream
;
3240 } else if (codec_type
== AVMEDIA_TYPE_AUDIO
) {
3241 start_index
= is
->last_audio_stream
;
3242 old_index
= is
->audio_stream
;
3244 start_index
= is
->last_subtitle_stream
;
3245 old_index
= is
->subtitle_stream
;
3247 stream_index
= start_index
;
3249 if (codec_type
!= AVMEDIA_TYPE_VIDEO
&& is
->video_stream
!= -1) {
3250 p
= av_find_program_from_stream(ic
, NULL
, is
->video_stream
);
3252 nb_streams
= p
->nb_stream_indexes
;
3253 for (start_index
= 0; start_index
< nb_streams
; start_index
++)
3254 if (p
->stream_index
[start_index
] == stream_index
)
3256 if (start_index
== nb_streams
)
3258 stream_index
= start_index
;
3263 if (++stream_index
>= nb_streams
)
3265 if (codec_type
== AVMEDIA_TYPE_SUBTITLE
)
3268 is
->last_subtitle_stream
= -1;
3271 if (start_index
== -1)
3275 if (stream_index
== start_index
)
3277 st
= is
->ic
->streams
[p
? p
->stream_index
[stream_index
] : stream_index
];
3278 if (st
->codec
->codec_type
== codec_type
) {
3279 /* check that parameters are OK */
3280 switch (codec_type
) {
3281 case AVMEDIA_TYPE_AUDIO
:
3282 if (st
->codec
->sample_rate
!= 0 &&
3283 st
->codec
->channels
!= 0)
3286 case AVMEDIA_TYPE_VIDEO
:
3287 case AVMEDIA_TYPE_SUBTITLE
:
3295 if (p
&& stream_index
!= -1)
3296 stream_index
= p
->stream_index
[stream_index
];
3297 av_log(NULL
, AV_LOG_INFO
, "Switch %s stream from #%d to #%d\n",
3298 av_get_media_type_string(codec_type
),
3302 stream_component_close(is
, old_index
);
3303 stream_component_open(is
, stream_index
);
3307 static void toggle_full_screen(VideoState
*is
)
3309 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3310 /* OS X needs to reallocate the SDL overlays */
3312 for (i
= 0; i
< VIDEO_PICTURE_QUEUE_SIZE
; i
++)
3313 is
->pictq
.queue
[i
].reallocate
= 1;
3315 is_full_screen
= !is_full_screen
;
3316 video_open(is
, 1, NULL
);
3319 static void toggle_audio_display(VideoState
*is
)
3321 int bgcolor
= SDL_MapRGB(screen
->format
, 0x00, 0x00, 0x00);
3322 int next
= is
->show_mode
;
3324 next
= (next
+ 1) % SHOW_MODE_NB
;
3325 } while (next
!= is
->show_mode
&& (next
== SHOW_MODE_VIDEO
&& !is
->video_st
|| next
!= SHOW_MODE_VIDEO
&& !is
->audio_st
));
3326 if (is
->show_mode
!= next
) {
3327 fill_rectangle(screen
,
3328 is
->xleft
, is
->ytop
, is
->width
, is
->height
,
3330 is
->force_refresh
= 1;
3331 is
->show_mode
= next
;
3335 static void refresh_loop_wait_event(VideoState
*is
, SDL_Event
*event
) {
3336 double remaining_time
= 0.0;
3338 while (!SDL_PeepEvents(event
, 1, SDL_GETEVENT
, SDL_ALLEVENTS
)) {
3339 if (!cursor_hidden
&& av_gettime_relative() - cursor_last_shown
> CURSOR_HIDE_DELAY
) {
3343 if (remaining_time
> 0.0)
3344 av_usleep((int64_t)(remaining_time
* 1000000.0));
3345 remaining_time
= REFRESH_RATE
;
3346 if (is
->show_mode
!= SHOW_MODE_NONE
&& (!is
->paused
|| is
->force_refresh
))
3347 video_refresh(is
, &remaining_time
);
3352 static void seek_chapter(VideoState
*is
, int incr
)
3354 int64_t pos
= get_master_clock(is
) * AV_TIME_BASE
;
3357 if (!is
->ic
->nb_chapters
)
3360 /* find the current chapter */
3361 for (i
= 0; i
< is
->ic
->nb_chapters
; i
++) {
3362 AVChapter
*ch
= is
->ic
->chapters
[i
];
3363 if (av_compare_ts(pos
, AV_TIME_BASE_Q
, ch
->start
, ch
->time_base
) < 0) {
3371 if (i
>= is
->ic
->nb_chapters
)
3374 av_log(NULL
, AV_LOG_VERBOSE
, "Seeking to chapter %d.\n", i
);
3375 stream_seek(is
, av_rescale_q(is
->ic
->chapters
[i
]->start
, is
->ic
->chapters
[i
]->time_base
,
3376 AV_TIME_BASE_Q
), 0, 0);
3379 /* handle an event sent by the GUI */
3380 static void event_loop(VideoState
*cur_stream
)
3383 double incr
, pos
, frac
;
3387 refresh_loop_wait_event(cur_stream
, &event
);
3388 switch (event
.type
) {
3390 if (exit_on_keydown
) {
3391 do_exit(cur_stream
);
3394 switch (event
.key
.keysym
.sym
) {
3397 do_exit(cur_stream
);
3400 toggle_full_screen(cur_stream
);
3401 cur_stream
->force_refresh
= 1;
3405 toggle_pause(cur_stream
);
3407 case SDLK_s
: // S: Step to next frame
3408 step_to_next_frame(cur_stream
);
3411 stream_cycle_channel(cur_stream
, AVMEDIA_TYPE_AUDIO
);
3414 stream_cycle_channel(cur_stream
, AVMEDIA_TYPE_VIDEO
);
3417 stream_cycle_channel(cur_stream
, AVMEDIA_TYPE_VIDEO
);
3418 stream_cycle_channel(cur_stream
, AVMEDIA_TYPE_AUDIO
);
3419 stream_cycle_channel(cur_stream
, AVMEDIA_TYPE_SUBTITLE
);
3422 stream_cycle_channel(cur_stream
, AVMEDIA_TYPE_SUBTITLE
);
3426 if (cur_stream
->show_mode
== SHOW_MODE_VIDEO
&& cur_stream
->vfilter_idx
< nb_vfilters
- 1) {
3427 if (++cur_stream
->vfilter_idx
>= nb_vfilters
)
3428 cur_stream
->vfilter_idx
= 0;
3430 cur_stream
->vfilter_idx
= 0;
3431 toggle_audio_display(cur_stream
);
3434 toggle_audio_display(cur_stream
);
3438 if (cur_stream
->ic
->nb_chapters
<= 1) {
3442 seek_chapter(cur_stream
, 1);
3445 if (cur_stream
->ic
->nb_chapters
<= 1) {
3449 seek_chapter(cur_stream
, -1);
3463 if (seek_by_bytes
) {
3465 if (pos
< 0 && cur_stream
->video_stream
>= 0)
3466 pos
= frame_queue_last_pos(&cur_stream
->pictq
);
3467 if (pos
< 0 && cur_stream
->audio_stream
>= 0)
3468 pos
= frame_queue_last_pos(&cur_stream
->sampq
);
3470 pos
= avio_tell(cur_stream
->ic
->pb
);
3471 if (cur_stream
->ic
->bit_rate
)
3472 incr
*= cur_stream
->ic
->bit_rate
/ 8.0;
3476 stream_seek(cur_stream
, pos
, incr
, 1);
3478 pos
= get_master_clock(cur_stream
);
3480 pos
= (double)cur_stream
->seek_pos
/ AV_TIME_BASE
;
3482 if (cur_stream
->ic
->start_time
!= AV_NOPTS_VALUE
&& pos
< cur_stream
->ic
->start_time
/ (double)AV_TIME_BASE
)
3483 pos
= cur_stream
->ic
->start_time
/ (double)AV_TIME_BASE
;
3484 stream_seek(cur_stream
, (int64_t)(pos
* AV_TIME_BASE
), (int64_t)(incr
* AV_TIME_BASE
), 0);
3491 case SDL_VIDEOEXPOSE
:
3492 cur_stream
->force_refresh
= 1;
3494 case SDL_MOUSEBUTTONDOWN
:
3495 if (exit_on_mousedown
) {
3496 do_exit(cur_stream
);
3499 case SDL_MOUSEMOTION
:
3500 if (cursor_hidden
) {
3504 cursor_last_shown
= av_gettime_relative();
3505 if (event
.type
== SDL_MOUSEBUTTONDOWN
) {
3508 if (event
.motion
.state
!= SDL_PRESSED
)
3512 if (seek_by_bytes
|| cur_stream
->ic
->duration
<= 0) {
3513 uint64_t size
= avio_size(cur_stream
->ic
->pb
);
3514 stream_seek(cur_stream
, size
*x
/cur_stream
->width
, 0, 1);
3518 int tns
, thh
, tmm
, tss
;
3519 tns
= cur_stream
->ic
->duration
/ 1000000LL;
3521 tmm
= (tns
% 3600) / 60;
3523 frac
= x
/ cur_stream
->width
;
3526 mm
= (ns
% 3600) / 60;
3528 av_log(NULL
, AV_LOG_INFO
,
3529 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac
*100,
3530 hh
, mm
, ss
, thh
, tmm
, tss
);
3531 ts
= frac
* cur_stream
->ic
->duration
;
3532 if (cur_stream
->ic
->start_time
!= AV_NOPTS_VALUE
)
3533 ts
+= cur_stream
->ic
->start_time
;
3534 stream_seek(cur_stream
, ts
, 0, 0);
3537 case SDL_VIDEORESIZE
:
3538 screen
= SDL_SetVideoMode(FFMIN(16383, event
.resize
.w
), event
.resize
.h
, 0,
3539 SDL_HWSURFACE
|(is_full_screen
?SDL_FULLSCREEN
:SDL_RESIZABLE
)|SDL_ASYNCBLIT
|SDL_HWACCEL
);
3541 av_log(NULL
, AV_LOG_FATAL
, "Failed to set video mode\n");
3542 do_exit(cur_stream
);
3544 screen_width
= cur_stream
->width
= screen
->w
;
3545 screen_height
= cur_stream
->height
= screen
->h
;
3546 cur_stream
->force_refresh
= 1;
3550 do_exit(cur_stream
);
3552 case FF_ALLOC_EVENT
:
3553 alloc_picture(event
.user
.data1
);
3561 static int opt_frame_size(void *optctx
, const char *opt
, const char *arg
)
3563 av_log(NULL
, AV_LOG_WARNING
, "Option -s is deprecated, use -video_size.\n");
3564 return opt_default(NULL
, "video_size", arg
);
3567 static int opt_width(void *optctx
, const char *opt
, const char *arg
)
3569 screen_width
= parse_number_or_die(opt
, arg
, OPT_INT64
, 1, INT_MAX
);
3573 static int opt_height(void *optctx
, const char *opt
, const char *arg
)
3575 screen_height
= parse_number_or_die(opt
, arg
, OPT_INT64
, 1, INT_MAX
);
3579 static int opt_format(void *optctx
, const char *opt
, const char *arg
)
3581 file_iformat
= av_find_input_format(arg
);
3582 if (!file_iformat
) {
3583 av_log(NULL
, AV_LOG_FATAL
, "Unknown input format: %s\n", arg
);
3584 return AVERROR(EINVAL
);
3589 static int opt_frame_pix_fmt(void *optctx
, const char *opt
, const char *arg
)
3591 av_log(NULL
, AV_LOG_WARNING
, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3592 return opt_default(NULL
, "pixel_format", arg
);
3595 static int opt_sync(void *optctx
, const char *opt
, const char *arg
)
3597 if (!strcmp(arg
, "audio"))
3598 av_sync_type
= AV_SYNC_AUDIO_MASTER
;
3599 else if (!strcmp(arg
, "video"))
3600 av_sync_type
= AV_SYNC_VIDEO_MASTER
;
3601 else if (!strcmp(arg
, "ext"))
3602 av_sync_type
= AV_SYNC_EXTERNAL_CLOCK
;
3604 av_log(NULL
, AV_LOG_ERROR
, "Unknown value for %s: %s\n", opt
, arg
);
3610 static int opt_seek(void *optctx
, const char *opt
, const char *arg
)
3612 start_time
= parse_time_or_die(opt
, arg
, 1);
3616 static int opt_duration(void *optctx
, const char *opt
, const char *arg
)
3618 duration
= parse_time_or_die(opt
, arg
, 1);
3622 static int opt_show_mode(void *optctx
, const char *opt
, const char *arg
)
3624 show_mode
= !strcmp(arg
, "video") ? SHOW_MODE_VIDEO
:
3625 !strcmp(arg
, "waves") ? SHOW_MODE_WAVES
:
3626 !strcmp(arg
, "rdft" ) ? SHOW_MODE_RDFT
:
3627 parse_number_or_die(opt
, arg
, OPT_INT
, 0, SHOW_MODE_NB
-1);
3631 static void opt_input_file(void *optctx
, const char *filename
)
3633 if (input_filename
) {
3634 av_log(NULL
, AV_LOG_FATAL
,
3635 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3636 filename
, input_filename
);
3639 if (!strcmp(filename
, "-"))
3641 input_filename
= filename
;
3644 static int opt_codec(void *optctx
, const char *opt
, const char *arg
)
3646 const char *spec
= strchr(opt
, ':');
3648 av_log(NULL
, AV_LOG_ERROR
,
3649 "No media specifier was specified in '%s' in option '%s'\n",
3651 return AVERROR(EINVAL
);
3655 case 'a' : audio_codec_name
= arg
; break;
3656 case 's' : subtitle_codec_name
= arg
; break;
3657 case 'v' : video_codec_name
= arg
; break;
3659 av_log(NULL
, AV_LOG_ERROR
,
3660 "Invalid media specifier '%s' in option '%s'\n", spec
, opt
);
3661 return AVERROR(EINVAL
);
3668 static const OptionDef options
[] = {
3669 #include "cmdutils_common_opts.h"
3670 { "x", HAS_ARG
, { .func_arg
= opt_width
}, "force displayed width", "width" },
3671 { "y", HAS_ARG
, { .func_arg
= opt_height
}, "force displayed height", "height" },
3672 { "s", HAS_ARG
| OPT_VIDEO
, { .func_arg
= opt_frame_size
}, "set frame size (WxH or abbreviation)", "size" },
3673 { "fs", OPT_BOOL
, { &is_full_screen
}, "force full screen" },
3674 { "an", OPT_BOOL
, { &audio_disable
}, "disable audio" },
3675 { "vn", OPT_BOOL
, { &video_disable
}, "disable video" },
3676 { "sn", OPT_BOOL
, { &subtitle_disable
}, "disable subtitling" },
3677 { "ast", OPT_INT
| HAS_ARG
| OPT_EXPERT
, { &wanted_stream
[AVMEDIA_TYPE_AUDIO
] }, "select desired audio stream", "stream_number" },
3678 { "vst", OPT_INT
| HAS_ARG
| OPT_EXPERT
, { &wanted_stream
[AVMEDIA_TYPE_VIDEO
] }, "select desired video stream", "stream_number" },
3679 { "sst", OPT_INT
| HAS_ARG
| OPT_EXPERT
, { &wanted_stream
[AVMEDIA_TYPE_SUBTITLE
] }, "select desired subtitle stream", "stream_number" },
3680 { "ss", HAS_ARG
, { .func_arg
= opt_seek
}, "seek to a given position in seconds", "pos" },
3681 { "t", HAS_ARG
, { .func_arg
= opt_duration
}, "play \"duration\" seconds of audio/video", "duration" },
3682 { "bytes", OPT_INT
| HAS_ARG
, { &seek_by_bytes
}, "seek by bytes 0=off 1=on -1=auto", "val" },
3683 { "nodisp", OPT_BOOL
, { &display_disable
}, "disable graphical display" },
3684 { "f", HAS_ARG
, { .func_arg
= opt_format
}, "force format", "fmt" },
3685 { "pix_fmt", HAS_ARG
| OPT_EXPERT
| OPT_VIDEO
, { .func_arg
= opt_frame_pix_fmt
}, "set pixel format", "format" },
3686 { "stats", OPT_BOOL
| OPT_EXPERT
, { &show_status
}, "show status", "" },
3687 { "fast", OPT_BOOL
| OPT_EXPERT
, { &fast
}, "non spec compliant optimizations", "" },
3688 { "genpts", OPT_BOOL
| OPT_EXPERT
, { &genpts
}, "generate pts", "" },
3689 { "drp", OPT_INT
| HAS_ARG
| OPT_EXPERT
, { &decoder_reorder_pts
}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3690 { "lowres", OPT_INT
| HAS_ARG
| OPT_EXPERT
, { &lowres
}, "", "" },
3691 { "sync", HAS_ARG
| OPT_EXPERT
, { .func_arg
= opt_sync
}, "set audio-video sync. type (type=audio/video/ext)", "type" },
3692 { "autoexit", OPT_BOOL
| OPT_EXPERT
, { &autoexit
}, "exit at the end", "" },
3693 { "exitonkeydown", OPT_BOOL
| OPT_EXPERT
, { &exit_on_keydown
}, "exit on key down", "" },
3694 { "exitonmousedown", OPT_BOOL
| OPT_EXPERT
, { &exit_on_mousedown
}, "exit on mouse down", "" },
3695 { "loop", OPT_INT
| HAS_ARG
| OPT_EXPERT
, { &loop
}, "set number of times the playback shall be looped", "loop count" },
3696 { "framedrop", OPT_BOOL
| OPT_EXPERT
, { &framedrop
}, "drop frames when cpu is too slow", "" },
3697 { "infbuf", OPT_BOOL
| OPT_EXPERT
, { &infinite_buffer
}, "don't limit the input buffer size (useful with realtime streams)", "" },
3698 { "window_title", OPT_STRING
| HAS_ARG
, { &window_title
}, "set window title", "window title" },
3700 { "vf", OPT_EXPERT
| HAS_ARG
, { .func_arg
= opt_add_vfilter
}, "set video filters", "filter_graph" },
3701 { "af", OPT_STRING
| HAS_ARG
, { &afilters
}, "set audio filters", "filter_graph" },
3703 { "rdftspeed", OPT_INT
| HAS_ARG
| OPT_AUDIO
| OPT_EXPERT
, { &rdftspeed
}, "rdft speed", "msecs" },
3704 { "showmode", HAS_ARG
, { .func_arg
= opt_show_mode
}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3705 { "default", HAS_ARG
| OPT_AUDIO
| OPT_VIDEO
| OPT_EXPERT
, { .func_arg
= opt_default
}, "generic catch all option", "" },
3706 { "i", OPT_BOOL
, { &dummy
}, "read specified file", "input_file"},
3707 { "codec", HAS_ARG
, { .func_arg
= opt_codec
}, "force decoder", "decoder_name" },
3708 { "acodec", HAS_ARG
| OPT_STRING
| OPT_EXPERT
, { &audio_codec_name
}, "force audio decoder", "decoder_name" },
3709 { "scodec", HAS_ARG
| OPT_STRING
| OPT_EXPERT
, { &subtitle_codec_name
}, "force subtitle decoder", "decoder_name" },
3710 { "vcodec", HAS_ARG
| OPT_STRING
| OPT_EXPERT
, { &video_codec_name
}, "force video decoder", "decoder_name" },
3711 { "autorotate", OPT_BOOL
, { &autorotate
}, "automatically rotate video", "" },
3715 static void show_usage(void)
3717 av_log(NULL
, AV_LOG_INFO
, "Simple media player\n");
3718 av_log(NULL
, AV_LOG_INFO
, "usage: %s [options] input_file\n", program_name
);
3719 av_log(NULL
, AV_LOG_INFO
, "\n");
3722 void show_help_default(const char *opt
, const char *arg
)
3724 av_log_set_callback(log_callback_help
);
3726 show_help_options(options
, "Main options:", 0, OPT_EXPERT
, 0);
3727 show_help_options(options
, "Advanced options:", OPT_EXPERT
, 0, 0);
3729 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM
);
3730 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM
);
3731 #if !CONFIG_AVFILTER
3732 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM
);
3734 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM
);
3736 printf("\nWhile playing:\n"
3738 "f toggle full screen\n"
3740 "a cycle audio channel in the current program\n"
3741 "v cycle video channel\n"
3742 "t cycle subtitle channel in the current program\n"
3744 "w cycle video filters or show modes\n"
3745 "s activate frame-step mode\n"
3746 "left/right seek backward/forward 10 seconds\n"
3747 "down/up seek backward/forward 1 minute\n"
3748 "page down/page up seek backward/forward 10 minutes\n"
3749 "mouse click seek to percentage in file corresponding to fraction of width\n"
3753 static int lockmgr(void **mtx
, enum AVLockOp op
)
3756 case AV_LOCK_CREATE
:
3757 *mtx
= SDL_CreateMutex();
3761 case AV_LOCK_OBTAIN
:
3762 return !!SDL_LockMutex(*mtx
);
3763 case AV_LOCK_RELEASE
:
3764 return !!SDL_UnlockMutex(*mtx
);
3765 case AV_LOCK_DESTROY
:
3766 SDL_DestroyMutex(*mtx
);
3772 /* Called from the main */
3773 int main(int argc
, char **argv
)
3777 char dummy_videodriver
[] = "SDL_VIDEODRIVER=dummy";
3779 av_log_set_flags(AV_LOG_SKIP_REPEATED
);
3780 parse_loglevel(argc
, argv
, options
);
3782 /* register all codecs, demux and protocols */
3784 avdevice_register_all();
3787 avfilter_register_all();
3790 avformat_network_init();
3794 signal(SIGINT
, sigterm_handler
); /* Interrupt (ANSI). */
3795 signal(SIGTERM
, sigterm_handler
); /* Termination (ANSI). */
3797 show_banner(argc
, argv
, options
);
3799 parse_options(NULL
, argc
, argv
, options
, opt_input_file
);
3801 if (!input_filename
) {
3803 av_log(NULL
, AV_LOG_FATAL
, "An input file must be specified\n");
3804 av_log(NULL
, AV_LOG_FATAL
,
3805 "Use -h to get full help or, even better, run 'man %s'\n", program_name
);
3809 if (display_disable
) {
3812 flags
= SDL_INIT_VIDEO
| SDL_INIT_AUDIO
| SDL_INIT_TIMER
;
3814 flags
&= ~SDL_INIT_AUDIO
;
3815 if (display_disable
)
3816 SDL_putenv(dummy_videodriver
); /* For the event queue, we always need a video driver. */
3817 #if !defined(_WIN32) && !defined(__APPLE__)
3818 flags
|= SDL_INIT_EVENTTHREAD
; /* Not supported on Windows or Mac OS X */
3820 if (SDL_Init (flags
)) {
3821 av_log(NULL
, AV_LOG_FATAL
, "Could not initialize SDL - %s\n", SDL_GetError());
3822 av_log(NULL
, AV_LOG_FATAL
, "(Did you set the DISPLAY variable?)\n");
3826 if (!display_disable
) {
3827 const SDL_VideoInfo
*vi
= SDL_GetVideoInfo();
3828 fs_screen_width
= vi
->current_w
;
3829 fs_screen_height
= vi
->current_h
;
3832 SDL_EventState(SDL_ACTIVEEVENT
, SDL_IGNORE
);
3833 SDL_EventState(SDL_SYSWMEVENT
, SDL_IGNORE
);
3834 SDL_EventState(SDL_USEREVENT
, SDL_IGNORE
);
3836 if (av_lockmgr_register(lockmgr
)) {
3837 av_log(NULL
, AV_LOG_FATAL
, "Could not initialize lock manager!\n");
3841 av_init_packet(&flush_pkt
);
3842 flush_pkt
.data
= (uint8_t *)&flush_pkt
;
3844 is
= stream_open(input_filename
, file_iformat
);
3846 av_log(NULL
, AV_LOG_FATAL
, "Failed to initialize VideoState!\n");